/*eslint-disable block-scoped-var, id-length, no-control-regex, no-magic-numbers, no-prototype-builtins, no-redeclare, no-shadow, no-var, sort-vars*/
"use strict";

var $protobuf = require("protobufjs/minimal.js");

// Common aliases
var $Reader = $protobuf.Reader, $Writer = $protobuf.Writer, $util = $protobuf.util;

// Exported root namespace
var $root = $protobuf.roots["default"] || ($protobuf.roots["default"] = {});

$root.communicator_objects = (function() {

    /**
     * Namespace communicator_objects.
     * @exports communicator_objects
     * @namespace
     */
    var communicator_objects = {};

    communicator_objects.AgentActionProto = (function() {

        /**
         * Properties of an AgentActionProto.
         * @memberof communicator_objects
         * @interface IAgentActionProto
         * @property {Array.<number>|null} [vectorActionsDeprecated] AgentActionProto vectorActionsDeprecated
         * @property {number|null} [value] AgentActionProto value
         * @property {Array.<number>|null} [continuousActions] AgentActionProto continuousActions
         * @property {Array.<number>|null} [discreteActions] AgentActionProto discreteActions
         */

        /**
         * Constructs a new AgentActionProto.
         * @memberof communicator_objects
         * @classdesc Represents an AgentActionProto.
         * @implements IAgentActionProto
         * @constructor
         * @param {communicator_objects.IAgentActionProto=} [properties] Properties to set
         */
        function AgentActionProto(properties) {
            this.vectorActionsDeprecated = [];
            this.continuousActions = [];
            this.discreteActions = [];
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * AgentActionProto vectorActionsDeprecated.
         * @member {Array.<number>} vectorActionsDeprecated
         * @memberof communicator_objects.AgentActionProto
         * @instance
         */
        AgentActionProto.prototype.vectorActionsDeprecated = $util.emptyArray;

        /**
         * AgentActionProto value.
         * @member {number} value
         * @memberof communicator_objects.AgentActionProto
         * @instance
         */
        AgentActionProto.prototype.value = 0;

        /**
         * AgentActionProto continuousActions.
         * @member {Array.<number>} continuousActions
         * @memberof communicator_objects.AgentActionProto
         * @instance
         */
        AgentActionProto.prototype.continuousActions = $util.emptyArray;

        /**
         * AgentActionProto discreteActions.
         * @member {Array.<number>} discreteActions
         * @memberof communicator_objects.AgentActionProto
         * @instance
         */
        AgentActionProto.prototype.discreteActions = $util.emptyArray;

        /**
         * Creates a new AgentActionProto instance using the specified properties.
         * @function create
         * @memberof communicator_objects.AgentActionProto
         * @static
         * @param {communicator_objects.IAgentActionProto=} [properties] Properties to set
         * @returns {communicator_objects.AgentActionProto} AgentActionProto instance
         */
        AgentActionProto.create = function create(properties) {
            return new AgentActionProto(properties);
        };

        /**
         * Encodes the specified AgentActionProto message. Does not implicitly {@link communicator_objects.AgentActionProto.verify|verify} messages.
         * @function encode
         * @memberof communicator_objects.AgentActionProto
         * @static
         * @param {communicator_objects.IAgentActionProto} message AgentActionProto message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        AgentActionProto.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.vectorActionsDeprecated != null && message.vectorActionsDeprecated.length) {
                writer.uint32(/* id 1, wireType 2 =*/10).fork();
                for (var i = 0; i < message.vectorActionsDeprecated.length; ++i)
                    writer.float(message.vectorActionsDeprecated[i]);
                writer.ldelim();
            }
            if (message.value != null && Object.hasOwnProperty.call(message, "value"))
                writer.uint32(/* id 4, wireType 5 =*/37).float(message.value);
            if (message.continuousActions != null && message.continuousActions.length) {
                writer.uint32(/* id 6, wireType 2 =*/50).fork();
                for (var i = 0; i < message.continuousActions.length; ++i)
                    writer.float(message.continuousActions[i]);
                writer.ldelim();
            }
            if (message.discreteActions != null && message.discreteActions.length) {
                writer.uint32(/* id 7, wireType 2 =*/58).fork();
                for (var i = 0; i < message.discreteActions.length; ++i)
                    writer.int32(message.discreteActions[i]);
                writer.ldelim();
            }
            return writer;
        };

        /**
         * Encodes the specified AgentActionProto message, length delimited. Does not implicitly {@link communicator_objects.AgentActionProto.verify|verify} messages.
         * @function encodeDelimited
         * @memberof communicator_objects.AgentActionProto
         * @static
         * @param {communicator_objects.IAgentActionProto} message AgentActionProto message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        AgentActionProto.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes an AgentActionProto message from the specified reader or buffer.
         * @function decode
         * @memberof communicator_objects.AgentActionProto
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {communicator_objects.AgentActionProto} AgentActionProto
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        AgentActionProto.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.communicator_objects.AgentActionProto();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    if (!(message.vectorActionsDeprecated && message.vectorActionsDeprecated.length))
                        message.vectorActionsDeprecated = [];
                    if ((tag & 7) === 2) {
                        var end2 = reader.uint32() + reader.pos;
                        while (reader.pos < end2)
                            message.vectorActionsDeprecated.push(reader.float());
                    } else
                        message.vectorActionsDeprecated.push(reader.float());
                    break;
                case 4:
                    message.value = reader.float();
                    break;
                case 6:
                    if (!(message.continuousActions && message.continuousActions.length))
                        message.continuousActions = [];
                    if ((tag & 7) === 2) {
                        var end2 = reader.uint32() + reader.pos;
                        while (reader.pos < end2)
                            message.continuousActions.push(reader.float());
                    } else
                        message.continuousActions.push(reader.float());
                    break;
                case 7:
                    if (!(message.discreteActions && message.discreteActions.length))
                        message.discreteActions = [];
                    if ((tag & 7) === 2) {
                        var end2 = reader.uint32() + reader.pos;
                        while (reader.pos < end2)
                            message.discreteActions.push(reader.int32());
                    } else
                        message.discreteActions.push(reader.int32());
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes an AgentActionProto message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof communicator_objects.AgentActionProto
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {communicator_objects.AgentActionProto} AgentActionProto
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        AgentActionProto.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies an AgentActionProto message.
         * @function verify
         * @memberof communicator_objects.AgentActionProto
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        AgentActionProto.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.vectorActionsDeprecated != null && message.hasOwnProperty("vectorActionsDeprecated")) {
                if (!Array.isArray(message.vectorActionsDeprecated))
                    return "vectorActionsDeprecated: array expected";
                for (var i = 0; i < message.vectorActionsDeprecated.length; ++i)
                    if (typeof message.vectorActionsDeprecated[i] !== "number")
                        return "vectorActionsDeprecated: number[] expected";
            }
            if (message.value != null && message.hasOwnProperty("value"))
                if (typeof message.value !== "number")
                    return "value: number expected";
            if (message.continuousActions != null && message.hasOwnProperty("continuousActions")) {
                if (!Array.isArray(message.continuousActions))
                    return "continuousActions: array expected";
                for (var i = 0; i < message.continuousActions.length; ++i)
                    if (typeof message.continuousActions[i] !== "number")
                        return "continuousActions: number[] expected";
            }
            if (message.discreteActions != null && message.hasOwnProperty("discreteActions")) {
                if (!Array.isArray(message.discreteActions))
                    return "discreteActions: array expected";
                for (var i = 0; i < message.discreteActions.length; ++i)
                    if (!$util.isInteger(message.discreteActions[i]))
                        return "discreteActions: integer[] expected";
            }
            return null;
        };

        /**
         * Creates an AgentActionProto message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof communicator_objects.AgentActionProto
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {communicator_objects.AgentActionProto} AgentActionProto
         */
        AgentActionProto.fromObject = function fromObject(object) {
            if (object instanceof $root.communicator_objects.AgentActionProto)
                return object;
            var message = new $root.communicator_objects.AgentActionProto();
            if (object.vectorActionsDeprecated) {
                if (!Array.isArray(object.vectorActionsDeprecated))
                    throw TypeError(".communicator_objects.AgentActionProto.vectorActionsDeprecated: array expected");
                message.vectorActionsDeprecated = [];
                for (var i = 0; i < object.vectorActionsDeprecated.length; ++i)
                    message.vectorActionsDeprecated[i] = Number(object.vectorActionsDeprecated[i]);
            }
            if (object.value != null)
                message.value = Number(object.value);
            if (object.continuousActions) {
                if (!Array.isArray(object.continuousActions))
                    throw TypeError(".communicator_objects.AgentActionProto.continuousActions: array expected");
                message.continuousActions = [];
                for (var i = 0; i < object.continuousActions.length; ++i)
                    message.continuousActions[i] = Number(object.continuousActions[i]);
            }
            if (object.discreteActions) {
                if (!Array.isArray(object.discreteActions))
                    throw TypeError(".communicator_objects.AgentActionProto.discreteActions: array expected");
                message.discreteActions = [];
                for (var i = 0; i < object.discreteActions.length; ++i)
                    message.discreteActions[i] = object.discreteActions[i] | 0;
            }
            return message;
        };

        /**
         * Creates a plain object from an AgentActionProto message. Also converts values to other types if specified.
         * @function toObject
         * @memberof communicator_objects.AgentActionProto
         * @static
         * @param {communicator_objects.AgentActionProto} message AgentActionProto
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        AgentActionProto.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.arrays || options.defaults) {
                object.vectorActionsDeprecated = [];
                object.continuousActions = [];
                object.discreteActions = [];
            }
            if (options.defaults)
                object.value = 0;
            if (message.vectorActionsDeprecated && message.vectorActionsDeprecated.length) {
                object.vectorActionsDeprecated = [];
                for (var j = 0; j < message.vectorActionsDeprecated.length; ++j)
                    object.vectorActionsDeprecated[j] = options.json && !isFinite(message.vectorActionsDeprecated[j]) ? String(message.vectorActionsDeprecated[j]) : message.vectorActionsDeprecated[j];
            }
            if (message.value != null && message.hasOwnProperty("value"))
                object.value = options.json && !isFinite(message.value) ? String(message.value) : message.value;
            if (message.continuousActions && message.continuousActions.length) {
                object.continuousActions = [];
                for (var j = 0; j < message.continuousActions.length; ++j)
                    object.continuousActions[j] = options.json && !isFinite(message.continuousActions[j]) ? String(message.continuousActions[j]) : message.continuousActions[j];
            }
            if (message.discreteActions && message.discreteActions.length) {
                object.discreteActions = [];
                for (var j = 0; j < message.discreteActions.length; ++j)
                    object.discreteActions[j] = message.discreteActions[j];
            }
            return object;
        };

        /**
         * Converts this AgentActionProto to JSON.
         * @function toJSON
         * @memberof communicator_objects.AgentActionProto
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        AgentActionProto.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return AgentActionProto;
    })();

    communicator_objects.AgentInfoProto = (function() {

        /**
         * Properties of an AgentInfoProto.
         * @memberof communicator_objects
         * @interface IAgentInfoProto
         * @property {number|null} [reward] AgentInfoProto reward
         * @property {boolean|null} [done] AgentInfoProto done
         * @property {boolean|null} [maxStepReached] AgentInfoProto maxStepReached
         * @property {number|null} [id] AgentInfoProto id
         * @property {Array.<boolean>|null} [actionMask] AgentInfoProto actionMask
         * @property {Array.<communicator_objects.IObservationProto>|null} [observations] AgentInfoProto observations
         * @property {number|null} [groupId] AgentInfoProto groupId
         * @property {number|null} [groupReward] AgentInfoProto groupReward
         */

        /**
         * Constructs a new AgentInfoProto.
         * @memberof communicator_objects
         * @classdesc Represents an AgentInfoProto.
         * @implements IAgentInfoProto
         * @constructor
         * @param {communicator_objects.IAgentInfoProto=} [properties] Properties to set
         */
        function AgentInfoProto(properties) {
            this.actionMask = [];
            this.observations = [];
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * AgentInfoProto reward.
         * @member {number} reward
         * @memberof communicator_objects.AgentInfoProto
         * @instance
         */
        AgentInfoProto.prototype.reward = 0;

        /**
         * AgentInfoProto done.
         * @member {boolean} done
         * @memberof communicator_objects.AgentInfoProto
         * @instance
         */
        AgentInfoProto.prototype.done = false;

        /**
         * AgentInfoProto maxStepReached.
         * @member {boolean} maxStepReached
         * @memberof communicator_objects.AgentInfoProto
         * @instance
         */
        AgentInfoProto.prototype.maxStepReached = false;

        /**
         * AgentInfoProto id.
         * @member {number} id
         * @memberof communicator_objects.AgentInfoProto
         * @instance
         */
        AgentInfoProto.prototype.id = 0;

        /**
         * AgentInfoProto actionMask.
         * @member {Array.<boolean>} actionMask
         * @memberof communicator_objects.AgentInfoProto
         * @instance
         */
        AgentInfoProto.prototype.actionMask = $util.emptyArray;

        /**
         * AgentInfoProto observations.
         * @member {Array.<communicator_objects.IObservationProto>} observations
         * @memberof communicator_objects.AgentInfoProto
         * @instance
         */
        AgentInfoProto.prototype.observations = $util.emptyArray;

        /**
         * AgentInfoProto groupId.
         * @member {number} groupId
         * @memberof communicator_objects.AgentInfoProto
         * @instance
         */
        AgentInfoProto.prototype.groupId = 0;

        /**
         * AgentInfoProto groupReward.
         * @member {number} groupReward
         * @memberof communicator_objects.AgentInfoProto
         * @instance
         */
        AgentInfoProto.prototype.groupReward = 0;

        /**
         * Creates a new AgentInfoProto instance using the specified properties.
         * @function create
         * @memberof communicator_objects.AgentInfoProto
         * @static
         * @param {communicator_objects.IAgentInfoProto=} [properties] Properties to set
         * @returns {communicator_objects.AgentInfoProto} AgentInfoProto instance
         */
        AgentInfoProto.create = function create(properties) {
            return new AgentInfoProto(properties);
        };

        /**
         * Encodes the specified AgentInfoProto message. Does not implicitly {@link communicator_objects.AgentInfoProto.verify|verify} messages.
         * @function encode
         * @memberof communicator_objects.AgentInfoProto
         * @static
         * @param {communicator_objects.IAgentInfoProto} message AgentInfoProto message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        AgentInfoProto.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.reward != null && Object.hasOwnProperty.call(message, "reward"))
                writer.uint32(/* id 7, wireType 5 =*/61).float(message.reward);
            if (message.done != null && Object.hasOwnProperty.call(message, "done"))
                writer.uint32(/* id 8, wireType 0 =*/64).bool(message.done);
            if (message.maxStepReached != null && Object.hasOwnProperty.call(message, "maxStepReached"))
                writer.uint32(/* id 9, wireType 0 =*/72).bool(message.maxStepReached);
            if (message.id != null && Object.hasOwnProperty.call(message, "id"))
                writer.uint32(/* id 10, wireType 0 =*/80).int32(message.id);
            if (message.actionMask != null && message.actionMask.length) {
                writer.uint32(/* id 11, wireType 2 =*/90).fork();
                for (var i = 0; i < message.actionMask.length; ++i)
                    writer.bool(message.actionMask[i]);
                writer.ldelim();
            }
            if (message.observations != null && message.observations.length)
                for (var i = 0; i < message.observations.length; ++i)
                    $root.communicator_objects.ObservationProto.encode(message.observations[i], writer.uint32(/* id 13, wireType 2 =*/106).fork()).ldelim();
            if (message.groupId != null && Object.hasOwnProperty.call(message, "groupId"))
                writer.uint32(/* id 14, wireType 0 =*/112).int32(message.groupId);
            if (message.groupReward != null && Object.hasOwnProperty.call(message, "groupReward"))
                writer.uint32(/* id 15, wireType 5 =*/125).float(message.groupReward);
            return writer;
        };

        /**
         * Encodes the specified AgentInfoProto message, length delimited. Does not implicitly {@link communicator_objects.AgentInfoProto.verify|verify} messages.
         * @function encodeDelimited
         * @memberof communicator_objects.AgentInfoProto
         * @static
         * @param {communicator_objects.IAgentInfoProto} message AgentInfoProto message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        AgentInfoProto.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes an AgentInfoProto message from the specified reader or buffer.
         * @function decode
         * @memberof communicator_objects.AgentInfoProto
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {communicator_objects.AgentInfoProto} AgentInfoProto
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        AgentInfoProto.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.communicator_objects.AgentInfoProto();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 7:
                    message.reward = reader.float();
                    break;
                case 8:
                    message.done = reader.bool();
                    break;
                case 9:
                    message.maxStepReached = reader.bool();
                    break;
                case 10:
                    message.id = reader.int32();
                    break;
                case 11:
                    if (!(message.actionMask && message.actionMask.length))
                        message.actionMask = [];
                    if ((tag & 7) === 2) {
                        var end2 = reader.uint32() + reader.pos;
                        while (reader.pos < end2)
                            message.actionMask.push(reader.bool());
                    } else
                        message.actionMask.push(reader.bool());
                    break;
                case 13:
                    if (!(message.observations && message.observations.length))
                        message.observations = [];
                    message.observations.push($root.communicator_objects.ObservationProto.decode(reader, reader.uint32()));
                    break;
                case 14:
                    message.groupId = reader.int32();
                    break;
                case 15:
                    message.groupReward = reader.float();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes an AgentInfoProto message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof communicator_objects.AgentInfoProto
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {communicator_objects.AgentInfoProto} AgentInfoProto
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        AgentInfoProto.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies an AgentInfoProto message.
         * @function verify
         * @memberof communicator_objects.AgentInfoProto
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        AgentInfoProto.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.reward != null && message.hasOwnProperty("reward"))
                if (typeof message.reward !== "number")
                    return "reward: number expected";
            if (message.done != null && message.hasOwnProperty("done"))
                if (typeof message.done !== "boolean")
                    return "done: boolean expected";
            if (message.maxStepReached != null && message.hasOwnProperty("maxStepReached"))
                if (typeof message.maxStepReached !== "boolean")
                    return "maxStepReached: boolean expected";
            if (message.id != null && message.hasOwnProperty("id"))
                if (!$util.isInteger(message.id))
                    return "id: integer expected";
            if (message.actionMask != null && message.hasOwnProperty("actionMask")) {
                if (!Array.isArray(message.actionMask))
                    return "actionMask: array expected";
                for (var i = 0; i < message.actionMask.length; ++i)
                    if (typeof message.actionMask[i] !== "boolean")
                        return "actionMask: boolean[] expected";
            }
            if (message.observations != null && message.hasOwnProperty("observations")) {
                if (!Array.isArray(message.observations))
                    return "observations: array expected";
                for (var i = 0; i < message.observations.length; ++i) {
                    var error = $root.communicator_objects.ObservationProto.verify(message.observations[i]);
                    if (error)
                        return "observations." + error;
                }
            }
            if (message.groupId != null && message.hasOwnProperty("groupId"))
                if (!$util.isInteger(message.groupId))
                    return "groupId: integer expected";
            if (message.groupReward != null && message.hasOwnProperty("groupReward"))
                if (typeof message.groupReward !== "number")
                    return "groupReward: number expected";
            return null;
        };

        /**
         * Creates an AgentInfoProto message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof communicator_objects.AgentInfoProto
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {communicator_objects.AgentInfoProto} AgentInfoProto
         */
        AgentInfoProto.fromObject = function fromObject(object) {
            if (object instanceof $root.communicator_objects.AgentInfoProto)
                return object;
            var message = new $root.communicator_objects.AgentInfoProto();
            if (object.reward != null)
                message.reward = Number(object.reward);
            if (object.done != null)
                message.done = Boolean(object.done);
            if (object.maxStepReached != null)
                message.maxStepReached = Boolean(object.maxStepReached);
            if (object.id != null)
                message.id = object.id | 0;
            if (object.actionMask) {
                if (!Array.isArray(object.actionMask))
                    throw TypeError(".communicator_objects.AgentInfoProto.actionMask: array expected");
                message.actionMask = [];
                for (var i = 0; i < object.actionMask.length; ++i)
                    message.actionMask[i] = Boolean(object.actionMask[i]);
            }
            if (object.observations) {
                if (!Array.isArray(object.observations))
                    throw TypeError(".communicator_objects.AgentInfoProto.observations: array expected");
                message.observations = [];
                for (var i = 0; i < object.observations.length; ++i) {
                    if (typeof object.observations[i] !== "object")
                        throw TypeError(".communicator_objects.AgentInfoProto.observations: object expected");
                    message.observations[i] = $root.communicator_objects.ObservationProto.fromObject(object.observations[i]);
                }
            }
            if (object.groupId != null)
                message.groupId = object.groupId | 0;
            if (object.groupReward != null)
                message.groupReward = Number(object.groupReward);
            return message;
        };

        /**
         * Creates a plain object from an AgentInfoProto message. Also converts values to other types if specified.
         * @function toObject
         * @memberof communicator_objects.AgentInfoProto
         * @static
         * @param {communicator_objects.AgentInfoProto} message AgentInfoProto
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        AgentInfoProto.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.arrays || options.defaults) {
                object.actionMask = [];
                object.observations = [];
            }
            if (options.defaults) {
                object.reward = 0;
                object.done = false;
                object.maxStepReached = false;
                object.id = 0;
                object.groupId = 0;
                object.groupReward = 0;
            }
            if (message.reward != null && message.hasOwnProperty("reward"))
                object.reward = options.json && !isFinite(message.reward) ? String(message.reward) : message.reward;
            if (message.done != null && message.hasOwnProperty("done"))
                object.done = message.done;
            if (message.maxStepReached != null && message.hasOwnProperty("maxStepReached"))
                object.maxStepReached = message.maxStepReached;
            if (message.id != null && message.hasOwnProperty("id"))
                object.id = message.id;
            if (message.actionMask && message.actionMask.length) {
                object.actionMask = [];
                for (var j = 0; j < message.actionMask.length; ++j)
                    object.actionMask[j] = message.actionMask[j];
            }
            if (message.observations && message.observations.length) {
                object.observations = [];
                for (var j = 0; j < message.observations.length; ++j)
                    object.observations[j] = $root.communicator_objects.ObservationProto.toObject(message.observations[j], options);
            }
            if (message.groupId != null && message.hasOwnProperty("groupId"))
                object.groupId = message.groupId;
            if (message.groupReward != null && message.hasOwnProperty("groupReward"))
                object.groupReward = options.json && !isFinite(message.groupReward) ? String(message.groupReward) : message.groupReward;
            return object;
        };

        /**
         * Converts this AgentInfoProto to JSON.
         * @function toJSON
         * @memberof communicator_objects.AgentInfoProto
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        AgentInfoProto.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return AgentInfoProto;
    })();

    communicator_objects.AgentInfoActionPairProto = (function() {

        /**
         * Properties of an AgentInfoActionPairProto.
         * @memberof communicator_objects
         * @interface IAgentInfoActionPairProto
         * @property {communicator_objects.IAgentInfoProto|null} [agentInfo] AgentInfoActionPairProto agentInfo
         * @property {communicator_objects.IAgentActionProto|null} [actionInfo] AgentInfoActionPairProto actionInfo
         */

        /**
         * Constructs a new AgentInfoActionPairProto.
         * @memberof communicator_objects
         * @classdesc Represents an AgentInfoActionPairProto.
         * @implements IAgentInfoActionPairProto
         * @constructor
         * @param {communicator_objects.IAgentInfoActionPairProto=} [properties] Properties to set
         */
        function AgentInfoActionPairProto(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * AgentInfoActionPairProto agentInfo.
         * @member {communicator_objects.IAgentInfoProto|null|undefined} agentInfo
         * @memberof communicator_objects.AgentInfoActionPairProto
         * @instance
         */
        AgentInfoActionPairProto.prototype.agentInfo = null;

        /**
         * AgentInfoActionPairProto actionInfo.
         * @member {communicator_objects.IAgentActionProto|null|undefined} actionInfo
         * @memberof communicator_objects.AgentInfoActionPairProto
         * @instance
         */
        AgentInfoActionPairProto.prototype.actionInfo = null;

        /**
         * Creates a new AgentInfoActionPairProto instance using the specified properties.
         * @function create
         * @memberof communicator_objects.AgentInfoActionPairProto
         * @static
         * @param {communicator_objects.IAgentInfoActionPairProto=} [properties] Properties to set
         * @returns {communicator_objects.AgentInfoActionPairProto} AgentInfoActionPairProto instance
         */
        AgentInfoActionPairProto.create = function create(properties) {
            return new AgentInfoActionPairProto(properties);
        };

        /**
         * Encodes the specified AgentInfoActionPairProto message. Does not implicitly {@link communicator_objects.AgentInfoActionPairProto.verify|verify} messages.
         * @function encode
         * @memberof communicator_objects.AgentInfoActionPairProto
         * @static
         * @param {communicator_objects.IAgentInfoActionPairProto} message AgentInfoActionPairProto message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        AgentInfoActionPairProto.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.agentInfo != null && Object.hasOwnProperty.call(message, "agentInfo"))
                $root.communicator_objects.AgentInfoProto.encode(message.agentInfo, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim();
            if (message.actionInfo != null && Object.hasOwnProperty.call(message, "actionInfo"))
                $root.communicator_objects.AgentActionProto.encode(message.actionInfo, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim();
            return writer;
        };

        /**
         * Encodes the specified AgentInfoActionPairProto message, length delimited. Does not implicitly {@link communicator_objects.AgentInfoActionPairProto.verify|verify} messages.
         * @function encodeDelimited
         * @memberof communicator_objects.AgentInfoActionPairProto
         * @static
         * @param {communicator_objects.IAgentInfoActionPairProto} message AgentInfoActionPairProto message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        AgentInfoActionPairProto.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes an AgentInfoActionPairProto message from the specified reader or buffer.
         * @function decode
         * @memberof communicator_objects.AgentInfoActionPairProto
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {communicator_objects.AgentInfoActionPairProto} AgentInfoActionPairProto
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        AgentInfoActionPairProto.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.communicator_objects.AgentInfoActionPairProto();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.agentInfo = $root.communicator_objects.AgentInfoProto.decode(reader, reader.uint32());
                    break;
                case 2:
                    message.actionInfo = $root.communicator_objects.AgentActionProto.decode(reader, reader.uint32());
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes an AgentInfoActionPairProto message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof communicator_objects.AgentInfoActionPairProto
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {communicator_objects.AgentInfoActionPairProto} AgentInfoActionPairProto
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        AgentInfoActionPairProto.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies an AgentInfoActionPairProto message.
         * @function verify
         * @memberof communicator_objects.AgentInfoActionPairProto
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        AgentInfoActionPairProto.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.agentInfo != null && message.hasOwnProperty("agentInfo")) {
                var error = $root.communicator_objects.AgentInfoProto.verify(message.agentInfo);
                if (error)
                    return "agentInfo." + error;
            }
            if (message.actionInfo != null && message.hasOwnProperty("actionInfo")) {
                var error = $root.communicator_objects.AgentActionProto.verify(message.actionInfo);
                if (error)
                    return "actionInfo." + error;
            }
            return null;
        };

        /**
         * Creates an AgentInfoActionPairProto message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof communicator_objects.AgentInfoActionPairProto
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {communicator_objects.AgentInfoActionPairProto} AgentInfoActionPairProto
         */
        AgentInfoActionPairProto.fromObject = function fromObject(object) {
            if (object instanceof $root.communicator_objects.AgentInfoActionPairProto)
                return object;
            var message = new $root.communicator_objects.AgentInfoActionPairProto();
            if (object.agentInfo != null) {
                if (typeof object.agentInfo !== "object")
                    throw TypeError(".communicator_objects.AgentInfoActionPairProto.agentInfo: object expected");
                message.agentInfo = $root.communicator_objects.AgentInfoProto.fromObject(object.agentInfo);
            }
            if (object.actionInfo != null) {
                if (typeof object.actionInfo !== "object")
                    throw TypeError(".communicator_objects.AgentInfoActionPairProto.actionInfo: object expected");
                message.actionInfo = $root.communicator_objects.AgentActionProto.fromObject(object.actionInfo);
            }
            return message;
        };

        /**
         * Creates a plain object from an AgentInfoActionPairProto message. Also converts values to other types if specified.
         * @function toObject
         * @memberof communicator_objects.AgentInfoActionPairProto
         * @static
         * @param {communicator_objects.AgentInfoActionPairProto} message AgentInfoActionPairProto
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        AgentInfoActionPairProto.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                object.agentInfo = null;
                object.actionInfo = null;
            }
            if (message.agentInfo != null && message.hasOwnProperty("agentInfo"))
                object.agentInfo = $root.communicator_objects.AgentInfoProto.toObject(message.agentInfo, options);
            if (message.actionInfo != null && message.hasOwnProperty("actionInfo"))
                object.actionInfo = $root.communicator_objects.AgentActionProto.toObject(message.actionInfo, options);
            return object;
        };

        /**
         * Converts this AgentInfoActionPairProto to JSON.
         * @function toJSON
         * @memberof communicator_objects.AgentInfoActionPairProto
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        AgentInfoActionPairProto.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return AgentInfoActionPairProto;
    })();

    communicator_objects.ActionSpecProto = (function() {

        /**
         * Properties of an ActionSpecProto.
         * @memberof communicator_objects
         * @interface IActionSpecProto
         * @property {number|null} [numContinuousActions] ActionSpecProto numContinuousActions
         * @property {number|null} [numDiscreteActions] ActionSpecProto numDiscreteActions
         * @property {Array.<number>|null} [discreteBranchSizes] ActionSpecProto discreteBranchSizes
         * @property {Array.<string>|null} [actionDescriptions] ActionSpecProto actionDescriptions
         */

        /**
         * Constructs a new ActionSpecProto.
         * @memberof communicator_objects
         * @classdesc Represents an ActionSpecProto.
         * @implements IActionSpecProto
         * @constructor
         * @param {communicator_objects.IActionSpecProto=} [properties] Properties to set
         */
        function ActionSpecProto(properties) {
            this.discreteBranchSizes = [];
            this.actionDescriptions = [];
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * ActionSpecProto numContinuousActions.
         * @member {number} numContinuousActions
         * @memberof communicator_objects.ActionSpecProto
         * @instance
         */
        ActionSpecProto.prototype.numContinuousActions = 0;

        /**
         * ActionSpecProto numDiscreteActions.
         * @member {number} numDiscreteActions
         * @memberof communicator_objects.ActionSpecProto
         * @instance
         */
        ActionSpecProto.prototype.numDiscreteActions = 0;

        /**
         * ActionSpecProto discreteBranchSizes.
         * @member {Array.<number>} discreteBranchSizes
         * @memberof communicator_objects.ActionSpecProto
         * @instance
         */
        ActionSpecProto.prototype.discreteBranchSizes = $util.emptyArray;

        /**
         * ActionSpecProto actionDescriptions.
         * @member {Array.<string>} actionDescriptions
         * @memberof communicator_objects.ActionSpecProto
         * @instance
         */
        ActionSpecProto.prototype.actionDescriptions = $util.emptyArray;

        /**
         * Creates a new ActionSpecProto instance using the specified properties.
         * @function create
         * @memberof communicator_objects.ActionSpecProto
         * @static
         * @param {communicator_objects.IActionSpecProto=} [properties] Properties to set
         * @returns {communicator_objects.ActionSpecProto} ActionSpecProto instance
         */
        ActionSpecProto.create = function create(properties) {
            return new ActionSpecProto(properties);
        };

        /**
         * Encodes the specified ActionSpecProto message. Does not implicitly {@link communicator_objects.ActionSpecProto.verify|verify} messages.
         * @function encode
         * @memberof communicator_objects.ActionSpecProto
         * @static
         * @param {communicator_objects.IActionSpecProto} message ActionSpecProto message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        ActionSpecProto.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.numContinuousActions != null && Object.hasOwnProperty.call(message, "numContinuousActions"))
                writer.uint32(/* id 1, wireType 0 =*/8).int32(message.numContinuousActions);
            if (message.numDiscreteActions != null && Object.hasOwnProperty.call(message, "numDiscreteActions"))
                writer.uint32(/* id 2, wireType 0 =*/16).int32(message.numDiscreteActions);
            if (message.discreteBranchSizes != null && message.discreteBranchSizes.length) {
                writer.uint32(/* id 3, wireType 2 =*/26).fork();
                for (var i = 0; i < message.discreteBranchSizes.length; ++i)
                    writer.int32(message.discreteBranchSizes[i]);
                writer.ldelim();
            }
            if (message.actionDescriptions != null && message.actionDescriptions.length)
                for (var i = 0; i < message.actionDescriptions.length; ++i)
                    writer.uint32(/* id 4, wireType 2 =*/34).string(message.actionDescriptions[i]);
            return writer;
        };

        /**
         * Encodes the specified ActionSpecProto message, length delimited. Does not implicitly {@link communicator_objects.ActionSpecProto.verify|verify} messages.
         * @function encodeDelimited
         * @memberof communicator_objects.ActionSpecProto
         * @static
         * @param {communicator_objects.IActionSpecProto} message ActionSpecProto message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        ActionSpecProto.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes an ActionSpecProto message from the specified reader or buffer.
         * @function decode
         * @memberof communicator_objects.ActionSpecProto
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {communicator_objects.ActionSpecProto} ActionSpecProto
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        ActionSpecProto.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.communicator_objects.ActionSpecProto();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.numContinuousActions = reader.int32();
                    break;
                case 2:
                    message.numDiscreteActions = reader.int32();
                    break;
                case 3:
                    if (!(message.discreteBranchSizes && message.discreteBranchSizes.length))
                        message.discreteBranchSizes = [];
                    if ((tag & 7) === 2) {
                        var end2 = reader.uint32() + reader.pos;
                        while (reader.pos < end2)
                            message.discreteBranchSizes.push(reader.int32());
                    } else
                        message.discreteBranchSizes.push(reader.int32());
                    break;
                case 4:
                    if (!(message.actionDescriptions && message.actionDescriptions.length))
                        message.actionDescriptions = [];
                    message.actionDescriptions.push(reader.string());
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes an ActionSpecProto message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof communicator_objects.ActionSpecProto
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {communicator_objects.ActionSpecProto} ActionSpecProto
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        ActionSpecProto.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies an ActionSpecProto message.
         * @function verify
         * @memberof communicator_objects.ActionSpecProto
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        ActionSpecProto.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.numContinuousActions != null && message.hasOwnProperty("numContinuousActions"))
                if (!$util.isInteger(message.numContinuousActions))
                    return "numContinuousActions: integer expected";
            if (message.numDiscreteActions != null && message.hasOwnProperty("numDiscreteActions"))
                if (!$util.isInteger(message.numDiscreteActions))
                    return "numDiscreteActions: integer expected";
            if (message.discreteBranchSizes != null && message.hasOwnProperty("discreteBranchSizes")) {
                if (!Array.isArray(message.discreteBranchSizes))
                    return "discreteBranchSizes: array expected";
                for (var i = 0; i < message.discreteBranchSizes.length; ++i)
                    if (!$util.isInteger(message.discreteBranchSizes[i]))
                        return "discreteBranchSizes: integer[] expected";
            }
            if (message.actionDescriptions != null && message.hasOwnProperty("actionDescriptions")) {
                if (!Array.isArray(message.actionDescriptions))
                    return "actionDescriptions: array expected";
                for (var i = 0; i < message.actionDescriptions.length; ++i)
                    if (!$util.isString(message.actionDescriptions[i]))
                        return "actionDescriptions: string[] expected";
            }
            return null;
        };

        /**
         * Creates an ActionSpecProto message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof communicator_objects.ActionSpecProto
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {communicator_objects.ActionSpecProto} ActionSpecProto
         */
        ActionSpecProto.fromObject = function fromObject(object) {
            if (object instanceof $root.communicator_objects.ActionSpecProto)
                return object;
            var message = new $root.communicator_objects.ActionSpecProto();
            if (object.numContinuousActions != null)
                message.numContinuousActions = object.numContinuousActions | 0;
            if (object.numDiscreteActions != null)
                message.numDiscreteActions = object.numDiscreteActions | 0;
            if (object.discreteBranchSizes) {
                if (!Array.isArray(object.discreteBranchSizes))
                    throw TypeError(".communicator_objects.ActionSpecProto.discreteBranchSizes: array expected");
                message.discreteBranchSizes = [];
                for (var i = 0; i < object.discreteBranchSizes.length; ++i)
                    message.discreteBranchSizes[i] = object.discreteBranchSizes[i] | 0;
            }
            if (object.actionDescriptions) {
                if (!Array.isArray(object.actionDescriptions))
                    throw TypeError(".communicator_objects.ActionSpecProto.actionDescriptions: array expected");
                message.actionDescriptions = [];
                for (var i = 0; i < object.actionDescriptions.length; ++i)
                    message.actionDescriptions[i] = String(object.actionDescriptions[i]);
            }
            return message;
        };

        /**
         * Creates a plain object from an ActionSpecProto message. Also converts values to other types if specified.
         * @function toObject
         * @memberof communicator_objects.ActionSpecProto
         * @static
         * @param {communicator_objects.ActionSpecProto} message ActionSpecProto
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        ActionSpecProto.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.arrays || options.defaults) {
                object.discreteBranchSizes = [];
                object.actionDescriptions = [];
            }
            if (options.defaults) {
                object.numContinuousActions = 0;
                object.numDiscreteActions = 0;
            }
            if (message.numContinuousActions != null && message.hasOwnProperty("numContinuousActions"))
                object.numContinuousActions = message.numContinuousActions;
            if (message.numDiscreteActions != null && message.hasOwnProperty("numDiscreteActions"))
                object.numDiscreteActions = message.numDiscreteActions;
            if (message.discreteBranchSizes && message.discreteBranchSizes.length) {
                object.discreteBranchSizes = [];
                for (var j = 0; j < message.discreteBranchSizes.length; ++j)
                    object.discreteBranchSizes[j] = message.discreteBranchSizes[j];
            }
            if (message.actionDescriptions && message.actionDescriptions.length) {
                object.actionDescriptions = [];
                for (var j = 0; j < message.actionDescriptions.length; ++j)
                    object.actionDescriptions[j] = message.actionDescriptions[j];
            }
            return object;
        };

        /**
         * Converts this ActionSpecProto to JSON.
         * @function toJSON
         * @memberof communicator_objects.ActionSpecProto
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        ActionSpecProto.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return ActionSpecProto;
    })();

    communicator_objects.BrainParametersProto = (function() {

        /**
         * Properties of a BrainParametersProto.
         * @memberof communicator_objects
         * @interface IBrainParametersProto
         * @property {Array.<number>|null} [vectorActionSizeDeprecated] BrainParametersProto vectorActionSizeDeprecated
         * @property {Array.<string>|null} [vectorActionDescriptionsDeprecated] BrainParametersProto vectorActionDescriptionsDeprecated
         * @property {communicator_objects.SpaceTypeProto|null} [vectorActionSpaceTypeDeprecated] BrainParametersProto vectorActionSpaceTypeDeprecated
         * @property {string|null} [brainName] BrainParametersProto brainName
         * @property {boolean|null} [isTraining] BrainParametersProto isTraining
         * @property {communicator_objects.IActionSpecProto|null} [actionSpec] BrainParametersProto actionSpec
         */

        /**
         * Constructs a new BrainParametersProto.
         * @memberof communicator_objects
         * @classdesc Represents a BrainParametersProto.
         * @implements IBrainParametersProto
         * @constructor
         * @param {communicator_objects.IBrainParametersProto=} [properties] Properties to set
         */
        function BrainParametersProto(properties) {
            this.vectorActionSizeDeprecated = [];
            this.vectorActionDescriptionsDeprecated = [];
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * BrainParametersProto vectorActionSizeDeprecated.
         * @member {Array.<number>} vectorActionSizeDeprecated
         * @memberof communicator_objects.BrainParametersProto
         * @instance
         */
        BrainParametersProto.prototype.vectorActionSizeDeprecated = $util.emptyArray;

        /**
         * BrainParametersProto vectorActionDescriptionsDeprecated.
         * @member {Array.<string>} vectorActionDescriptionsDeprecated
         * @memberof communicator_objects.BrainParametersProto
         * @instance
         */
        BrainParametersProto.prototype.vectorActionDescriptionsDeprecated = $util.emptyArray;

        /**
         * BrainParametersProto vectorActionSpaceTypeDeprecated.
         * @member {communicator_objects.SpaceTypeProto} vectorActionSpaceTypeDeprecated
         * @memberof communicator_objects.BrainParametersProto
         * @instance
         */
        BrainParametersProto.prototype.vectorActionSpaceTypeDeprecated = 0;

        /**
         * BrainParametersProto brainName.
         * @member {string} brainName
         * @memberof communicator_objects.BrainParametersProto
         * @instance
         */
        BrainParametersProto.prototype.brainName = "";

        /**
         * BrainParametersProto isTraining.
         * @member {boolean} isTraining
         * @memberof communicator_objects.BrainParametersProto
         * @instance
         */
        BrainParametersProto.prototype.isTraining = false;

        /**
         * BrainParametersProto actionSpec.
         * @member {communicator_objects.IActionSpecProto|null|undefined} actionSpec
         * @memberof communicator_objects.BrainParametersProto
         * @instance
         */
        BrainParametersProto.prototype.actionSpec = null;

        /**
         * Creates a new BrainParametersProto instance using the specified properties.
         * @function create
         * @memberof communicator_objects.BrainParametersProto
         * @static
         * @param {communicator_objects.IBrainParametersProto=} [properties] Properties to set
         * @returns {communicator_objects.BrainParametersProto} BrainParametersProto instance
         */
        BrainParametersProto.create = function create(properties) {
            return new BrainParametersProto(properties);
        };

        /**
         * Encodes the specified BrainParametersProto message. Does not implicitly {@link communicator_objects.BrainParametersProto.verify|verify} messages.
         * @function encode
         * @memberof communicator_objects.BrainParametersProto
         * @static
         * @param {communicator_objects.IBrainParametersProto} message BrainParametersProto message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        BrainParametersProto.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.vectorActionSizeDeprecated != null && message.vectorActionSizeDeprecated.length) {
                writer.uint32(/* id 3, wireType 2 =*/26).fork();
                for (var i = 0; i < message.vectorActionSizeDeprecated.length; ++i)
                    writer.int32(message.vectorActionSizeDeprecated[i]);
                writer.ldelim();
            }
            if (message.vectorActionDescriptionsDeprecated != null && message.vectorActionDescriptionsDeprecated.length)
                for (var i = 0; i < message.vectorActionDescriptionsDeprecated.length; ++i)
                    writer.uint32(/* id 5, wireType 2 =*/42).string(message.vectorActionDescriptionsDeprecated[i]);
            if (message.vectorActionSpaceTypeDeprecated != null && Object.hasOwnProperty.call(message, "vectorActionSpaceTypeDeprecated"))
                writer.uint32(/* id 6, wireType 0 =*/48).int32(message.vectorActionSpaceTypeDeprecated);
            if (message.brainName != null && Object.hasOwnProperty.call(message, "brainName"))
                writer.uint32(/* id 7, wireType 2 =*/58).string(message.brainName);
            if (message.isTraining != null && Object.hasOwnProperty.call(message, "isTraining"))
                writer.uint32(/* id 8, wireType 0 =*/64).bool(message.isTraining);
            if (message.actionSpec != null && Object.hasOwnProperty.call(message, "actionSpec"))
                $root.communicator_objects.ActionSpecProto.encode(message.actionSpec, writer.uint32(/* id 9, wireType 2 =*/74).fork()).ldelim();
            return writer;
        };

        /**
         * Encodes the specified BrainParametersProto message, length delimited. Does not implicitly {@link communicator_objects.BrainParametersProto.verify|verify} messages.
         * @function encodeDelimited
         * @memberof communicator_objects.BrainParametersProto
         * @static
         * @param {communicator_objects.IBrainParametersProto} message BrainParametersProto message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        BrainParametersProto.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a BrainParametersProto message from the specified reader or buffer.
         * @function decode
         * @memberof communicator_objects.BrainParametersProto
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {communicator_objects.BrainParametersProto} BrainParametersProto
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        BrainParametersProto.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.communicator_objects.BrainParametersProto();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 3:
                    if (!(message.vectorActionSizeDeprecated && message.vectorActionSizeDeprecated.length))
                        message.vectorActionSizeDeprecated = [];
                    if ((tag & 7) === 2) {
                        var end2 = reader.uint32() + reader.pos;
                        while (reader.pos < end2)
                            message.vectorActionSizeDeprecated.push(reader.int32());
                    } else
                        message.vectorActionSizeDeprecated.push(reader.int32());
                    break;
                case 5:
                    if (!(message.vectorActionDescriptionsDeprecated && message.vectorActionDescriptionsDeprecated.length))
                        message.vectorActionDescriptionsDeprecated = [];
                    message.vectorActionDescriptionsDeprecated.push(reader.string());
                    break;
                case 6:
                    message.vectorActionSpaceTypeDeprecated = reader.int32();
                    break;
                case 7:
                    message.brainName = reader.string();
                    break;
                case 8:
                    message.isTraining = reader.bool();
                    break;
                case 9:
                    message.actionSpec = $root.communicator_objects.ActionSpecProto.decode(reader, reader.uint32());
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a BrainParametersProto message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof communicator_objects.BrainParametersProto
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {communicator_objects.BrainParametersProto} BrainParametersProto
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        BrainParametersProto.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a BrainParametersProto message.
         * @function verify
         * @memberof communicator_objects.BrainParametersProto
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        BrainParametersProto.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.vectorActionSizeDeprecated != null && message.hasOwnProperty("vectorActionSizeDeprecated")) {
                if (!Array.isArray(message.vectorActionSizeDeprecated))
                    return "vectorActionSizeDeprecated: array expected";
                for (var i = 0; i < message.vectorActionSizeDeprecated.length; ++i)
                    if (!$util.isInteger(message.vectorActionSizeDeprecated[i]))
                        return "vectorActionSizeDeprecated: integer[] expected";
            }
            if (message.vectorActionDescriptionsDeprecated != null && message.hasOwnProperty("vectorActionDescriptionsDeprecated")) {
                if (!Array.isArray(message.vectorActionDescriptionsDeprecated))
                    return "vectorActionDescriptionsDeprecated: array expected";
                for (var i = 0; i < message.vectorActionDescriptionsDeprecated.length; ++i)
                    if (!$util.isString(message.vectorActionDescriptionsDeprecated[i]))
                        return "vectorActionDescriptionsDeprecated: string[] expected";
            }
            if (message.vectorActionSpaceTypeDeprecated != null && message.hasOwnProperty("vectorActionSpaceTypeDeprecated"))
                switch (message.vectorActionSpaceTypeDeprecated) {
                default:
                    return "vectorActionSpaceTypeDeprecated: enum value expected";
                case 0:
                case 1:
                    break;
                }
            if (message.brainName != null && message.hasOwnProperty("brainName"))
                if (!$util.isString(message.brainName))
                    return "brainName: string expected";
            if (message.isTraining != null && message.hasOwnProperty("isTraining"))
                if (typeof message.isTraining !== "boolean")
                    return "isTraining: boolean expected";
            if (message.actionSpec != null && message.hasOwnProperty("actionSpec")) {
                var error = $root.communicator_objects.ActionSpecProto.verify(message.actionSpec);
                if (error)
                    return "actionSpec." + error;
            }
            return null;
        };

        /**
         * Creates a BrainParametersProto message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof communicator_objects.BrainParametersProto
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {communicator_objects.BrainParametersProto} BrainParametersProto
         */
        BrainParametersProto.fromObject = function fromObject(object) {
            if (object instanceof $root.communicator_objects.BrainParametersProto)
                return object;
            var message = new $root.communicator_objects.BrainParametersProto();
            if (object.vectorActionSizeDeprecated) {
                if (!Array.isArray(object.vectorActionSizeDeprecated))
                    throw TypeError(".communicator_objects.BrainParametersProto.vectorActionSizeDeprecated: array expected");
                message.vectorActionSizeDeprecated = [];
                for (var i = 0; i < object.vectorActionSizeDeprecated.length; ++i)
                    message.vectorActionSizeDeprecated[i] = object.vectorActionSizeDeprecated[i] | 0;
            }
            if (object.vectorActionDescriptionsDeprecated) {
                if (!Array.isArray(object.vectorActionDescriptionsDeprecated))
                    throw TypeError(".communicator_objects.BrainParametersProto.vectorActionDescriptionsDeprecated: array expected");
                message.vectorActionDescriptionsDeprecated = [];
                for (var i = 0; i < object.vectorActionDescriptionsDeprecated.length; ++i)
                    message.vectorActionDescriptionsDeprecated[i] = String(object.vectorActionDescriptionsDeprecated[i]);
            }
            switch (object.vectorActionSpaceTypeDeprecated) {
            case "discrete":
            case 0:
                message.vectorActionSpaceTypeDeprecated = 0;
                break;
            case "continuous":
            case 1:
                message.vectorActionSpaceTypeDeprecated = 1;
                break;
            }
            if (object.brainName != null)
                message.brainName = String(object.brainName);
            if (object.isTraining != null)
                message.isTraining = Boolean(object.isTraining);
            if (object.actionSpec != null) {
                if (typeof object.actionSpec !== "object")
                    throw TypeError(".communicator_objects.BrainParametersProto.actionSpec: object expected");
                message.actionSpec = $root.communicator_objects.ActionSpecProto.fromObject(object.actionSpec);
            }
            return message;
        };

        /**
         * Creates a plain object from a BrainParametersProto message. Also converts values to other types if specified.
         * @function toObject
         * @memberof communicator_objects.BrainParametersProto
         * @static
         * @param {communicator_objects.BrainParametersProto} message BrainParametersProto
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        BrainParametersProto.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.arrays || options.defaults) {
                object.vectorActionSizeDeprecated = [];
                object.vectorActionDescriptionsDeprecated = [];
            }
            if (options.defaults) {
                object.vectorActionSpaceTypeDeprecated = options.enums === String ? "discrete" : 0;
                object.brainName = "";
                object.isTraining = false;
                object.actionSpec = null;
            }
            if (message.vectorActionSizeDeprecated && message.vectorActionSizeDeprecated.length) {
                object.vectorActionSizeDeprecated = [];
                for (var j = 0; j < message.vectorActionSizeDeprecated.length; ++j)
                    object.vectorActionSizeDeprecated[j] = message.vectorActionSizeDeprecated[j];
            }
            if (message.vectorActionDescriptionsDeprecated && message.vectorActionDescriptionsDeprecated.length) {
                object.vectorActionDescriptionsDeprecated = [];
                for (var j = 0; j < message.vectorActionDescriptionsDeprecated.length; ++j)
                    object.vectorActionDescriptionsDeprecated[j] = message.vectorActionDescriptionsDeprecated[j];
            }
            if (message.vectorActionSpaceTypeDeprecated != null && message.hasOwnProperty("vectorActionSpaceTypeDeprecated"))
                object.vectorActionSpaceTypeDeprecated = options.enums === String ? $root.communicator_objects.SpaceTypeProto[message.vectorActionSpaceTypeDeprecated] : message.vectorActionSpaceTypeDeprecated;
            if (message.brainName != null && message.hasOwnProperty("brainName"))
                object.brainName = message.brainName;
            if (message.isTraining != null && message.hasOwnProperty("isTraining"))
                object.isTraining = message.isTraining;
            if (message.actionSpec != null && message.hasOwnProperty("actionSpec"))
                object.actionSpec = $root.communicator_objects.ActionSpecProto.toObject(message.actionSpec, options);
            return object;
        };

        /**
         * Converts this BrainParametersProto to JSON.
         * @function toJSON
         * @memberof communicator_objects.BrainParametersProto
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        BrainParametersProto.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return BrainParametersProto;
    })();

    communicator_objects.UnityRLCapabilitiesProto = (function() {

        /**
         * Properties of an UnityRLCapabilitiesProto.
         * @memberof communicator_objects
         * @interface IUnityRLCapabilitiesProto
         * @property {boolean|null} [baseRLCapabilities] UnityRLCapabilitiesProto baseRLCapabilities
         * @property {boolean|null} [concatenatedPngObservations] UnityRLCapabilitiesProto concatenatedPngObservations
         * @property {boolean|null} [compressedChannelMapping] UnityRLCapabilitiesProto compressedChannelMapping
         * @property {boolean|null} [hybridActions] UnityRLCapabilitiesProto hybridActions
         * @property {boolean|null} [trainingAnalytics] UnityRLCapabilitiesProto trainingAnalytics
         * @property {boolean|null} [variableLengthObservation] UnityRLCapabilitiesProto variableLengthObservation
         * @property {boolean|null} [multiAgentGroups] UnityRLCapabilitiesProto multiAgentGroups
         */

        /**
         * Constructs a new UnityRLCapabilitiesProto.
         * @memberof communicator_objects
         * @classdesc Represents an UnityRLCapabilitiesProto.
         * @implements IUnityRLCapabilitiesProto
         * @constructor
         * @param {communicator_objects.IUnityRLCapabilitiesProto=} [properties] Properties to set
         */
        function UnityRLCapabilitiesProto(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * UnityRLCapabilitiesProto baseRLCapabilities.
         * @member {boolean} baseRLCapabilities
         * @memberof communicator_objects.UnityRLCapabilitiesProto
         * @instance
         */
        UnityRLCapabilitiesProto.prototype.baseRLCapabilities = false;

        /**
         * UnityRLCapabilitiesProto concatenatedPngObservations.
         * @member {boolean} concatenatedPngObservations
         * @memberof communicator_objects.UnityRLCapabilitiesProto
         * @instance
         */
        UnityRLCapabilitiesProto.prototype.concatenatedPngObservations = false;

        /**
         * UnityRLCapabilitiesProto compressedChannelMapping.
         * @member {boolean} compressedChannelMapping
         * @memberof communicator_objects.UnityRLCapabilitiesProto
         * @instance
         */
        UnityRLCapabilitiesProto.prototype.compressedChannelMapping = false;

        /**
         * UnityRLCapabilitiesProto hybridActions.
         * @member {boolean} hybridActions
         * @memberof communicator_objects.UnityRLCapabilitiesProto
         * @instance
         */
        UnityRLCapabilitiesProto.prototype.hybridActions = false;

        /**
         * UnityRLCapabilitiesProto trainingAnalytics.
         * @member {boolean} trainingAnalytics
         * @memberof communicator_objects.UnityRLCapabilitiesProto
         * @instance
         */
        UnityRLCapabilitiesProto.prototype.trainingAnalytics = false;

        /**
         * UnityRLCapabilitiesProto variableLengthObservation.
         * @member {boolean} variableLengthObservation
         * @memberof communicator_objects.UnityRLCapabilitiesProto
         * @instance
         */
        UnityRLCapabilitiesProto.prototype.variableLengthObservation = false;

        /**
         * UnityRLCapabilitiesProto multiAgentGroups.
         * @member {boolean} multiAgentGroups
         * @memberof communicator_objects.UnityRLCapabilitiesProto
         * @instance
         */
        UnityRLCapabilitiesProto.prototype.multiAgentGroups = false;

        /**
         * Creates a new UnityRLCapabilitiesProto instance using the specified properties.
         * @function create
         * @memberof communicator_objects.UnityRLCapabilitiesProto
         * @static
         * @param {communicator_objects.IUnityRLCapabilitiesProto=} [properties] Properties to set
         * @returns {communicator_objects.UnityRLCapabilitiesProto} UnityRLCapabilitiesProto instance
         */
        UnityRLCapabilitiesProto.create = function create(properties) {
            return new UnityRLCapabilitiesProto(properties);
        };

        /**
         * Encodes the specified UnityRLCapabilitiesProto message. Does not implicitly {@link communicator_objects.UnityRLCapabilitiesProto.verify|verify} messages.
         * @function encode
         * @memberof communicator_objects.UnityRLCapabilitiesProto
         * @static
         * @param {communicator_objects.IUnityRLCapabilitiesProto} message UnityRLCapabilitiesProto message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        UnityRLCapabilitiesProto.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.baseRLCapabilities != null && Object.hasOwnProperty.call(message, "baseRLCapabilities"))
                writer.uint32(/* id 1, wireType 0 =*/8).bool(message.baseRLCapabilities);
            if (message.concatenatedPngObservations != null && Object.hasOwnProperty.call(message, "concatenatedPngObservations"))
                writer.uint32(/* id 2, wireType 0 =*/16).bool(message.concatenatedPngObservations);
            if (message.compressedChannelMapping != null && Object.hasOwnProperty.call(message, "compressedChannelMapping"))
                writer.uint32(/* id 3, wireType 0 =*/24).bool(message.compressedChannelMapping);
            if (message.hybridActions != null && Object.hasOwnProperty.call(message, "hybridActions"))
                writer.uint32(/* id 4, wireType 0 =*/32).bool(message.hybridActions);
            if (message.trainingAnalytics != null && Object.hasOwnProperty.call(message, "trainingAnalytics"))
                writer.uint32(/* id 5, wireType 0 =*/40).bool(message.trainingAnalytics);
            if (message.variableLengthObservation != null && Object.hasOwnProperty.call(message, "variableLengthObservation"))
                writer.uint32(/* id 6, wireType 0 =*/48).bool(message.variableLengthObservation);
            if (message.multiAgentGroups != null && Object.hasOwnProperty.call(message, "multiAgentGroups"))
                writer.uint32(/* id 7, wireType 0 =*/56).bool(message.multiAgentGroups);
            return writer;
        };

        /**
         * Encodes the specified UnityRLCapabilitiesProto message, length delimited. Does not implicitly {@link communicator_objects.UnityRLCapabilitiesProto.verify|verify} messages.
         * @function encodeDelimited
         * @memberof communicator_objects.UnityRLCapabilitiesProto
         * @static
         * @param {communicator_objects.IUnityRLCapabilitiesProto} message UnityRLCapabilitiesProto message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        UnityRLCapabilitiesProto.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes an UnityRLCapabilitiesProto message from the specified reader or buffer.
         * @function decode
         * @memberof communicator_objects.UnityRLCapabilitiesProto
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {communicator_objects.UnityRLCapabilitiesProto} UnityRLCapabilitiesProto
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        UnityRLCapabilitiesProto.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.communicator_objects.UnityRLCapabilitiesProto();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.baseRLCapabilities = reader.bool();
                    break;
                case 2:
                    message.concatenatedPngObservations = reader.bool();
                    break;
                case 3:
                    message.compressedChannelMapping = reader.bool();
                    break;
                case 4:
                    message.hybridActions = reader.bool();
                    break;
                case 5:
                    message.trainingAnalytics = reader.bool();
                    break;
                case 6:
                    message.variableLengthObservation = reader.bool();
                    break;
                case 7:
                    message.multiAgentGroups = reader.bool();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes an UnityRLCapabilitiesProto message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof communicator_objects.UnityRLCapabilitiesProto
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {communicator_objects.UnityRLCapabilitiesProto} UnityRLCapabilitiesProto
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        UnityRLCapabilitiesProto.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies an UnityRLCapabilitiesProto message.
         * @function verify
         * @memberof communicator_objects.UnityRLCapabilitiesProto
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        UnityRLCapabilitiesProto.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.baseRLCapabilities != null && message.hasOwnProperty("baseRLCapabilities"))
                if (typeof message.baseRLCapabilities !== "boolean")
                    return "baseRLCapabilities: boolean expected";
            if (message.concatenatedPngObservations != null && message.hasOwnProperty("concatenatedPngObservations"))
                if (typeof message.concatenatedPngObservations !== "boolean")
                    return "concatenatedPngObservations: boolean expected";
            if (message.compressedChannelMapping != null && message.hasOwnProperty("compressedChannelMapping"))
                if (typeof message.compressedChannelMapping !== "boolean")
                    return "compressedChannelMapping: boolean expected";
            if (message.hybridActions != null && message.hasOwnProperty("hybridActions"))
                if (typeof message.hybridActions !== "boolean")
                    return "hybridActions: boolean expected";
            if (message.trainingAnalytics != null && message.hasOwnProperty("trainingAnalytics"))
                if (typeof message.trainingAnalytics !== "boolean")
                    return "trainingAnalytics: boolean expected";
            if (message.variableLengthObservation != null && message.hasOwnProperty("variableLengthObservation"))
                if (typeof message.variableLengthObservation !== "boolean")
                    return "variableLengthObservation: boolean expected";
            if (message.multiAgentGroups != null && message.hasOwnProperty("multiAgentGroups"))
                if (typeof message.multiAgentGroups !== "boolean")
                    return "multiAgentGroups: boolean expected";
            return null;
        };

        /**
         * Creates an UnityRLCapabilitiesProto message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof communicator_objects.UnityRLCapabilitiesProto
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {communicator_objects.UnityRLCapabilitiesProto} UnityRLCapabilitiesProto
         */
        UnityRLCapabilitiesProto.fromObject = function fromObject(object) {
            if (object instanceof $root.communicator_objects.UnityRLCapabilitiesProto)
                return object;
            var message = new $root.communicator_objects.UnityRLCapabilitiesProto();
            if (object.baseRLCapabilities != null)
                message.baseRLCapabilities = Boolean(object.baseRLCapabilities);
            if (object.concatenatedPngObservations != null)
                message.concatenatedPngObservations = Boolean(object.concatenatedPngObservations);
            if (object.compressedChannelMapping != null)
                message.compressedChannelMapping = Boolean(object.compressedChannelMapping);
            if (object.hybridActions != null)
                message.hybridActions = Boolean(object.hybridActions);
            if (object.trainingAnalytics != null)
                message.trainingAnalytics = Boolean(object.trainingAnalytics);
            if (object.variableLengthObservation != null)
                message.variableLengthObservation = Boolean(object.variableLengthObservation);
            if (object.multiAgentGroups != null)
                message.multiAgentGroups = Boolean(object.multiAgentGroups);
            return message;
        };

        /**
         * Creates a plain object from an UnityRLCapabilitiesProto message. Also converts values to other types if specified.
         * @function toObject
         * @memberof communicator_objects.UnityRLCapabilitiesProto
         * @static
         * @param {communicator_objects.UnityRLCapabilitiesProto} message UnityRLCapabilitiesProto
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        UnityRLCapabilitiesProto.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                object.baseRLCapabilities = false;
                object.concatenatedPngObservations = false;
                object.compressedChannelMapping = false;
                object.hybridActions = false;
                object.trainingAnalytics = false;
                object.variableLengthObservation = false;
                object.multiAgentGroups = false;
            }
            if (message.baseRLCapabilities != null && message.hasOwnProperty("baseRLCapabilities"))
                object.baseRLCapabilities = message.baseRLCapabilities;
            if (message.concatenatedPngObservations != null && message.hasOwnProperty("concatenatedPngObservations"))
                object.concatenatedPngObservations = message.concatenatedPngObservations;
            if (message.compressedChannelMapping != null && message.hasOwnProperty("compressedChannelMapping"))
                object.compressedChannelMapping = message.compressedChannelMapping;
            if (message.hybridActions != null && message.hasOwnProperty("hybridActions"))
                object.hybridActions = message.hybridActions;
            if (message.trainingAnalytics != null && message.hasOwnProperty("trainingAnalytics"))
                object.trainingAnalytics = message.trainingAnalytics;
            if (message.variableLengthObservation != null && message.hasOwnProperty("variableLengthObservation"))
                object.variableLengthObservation = message.variableLengthObservation;
            if (message.multiAgentGroups != null && message.hasOwnProperty("multiAgentGroups"))
                object.multiAgentGroups = message.multiAgentGroups;
            return object;
        };

        /**
         * Converts this UnityRLCapabilitiesProto to JSON.
         * @function toJSON
         * @memberof communicator_objects.UnityRLCapabilitiesProto
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        UnityRLCapabilitiesProto.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return UnityRLCapabilitiesProto;
    })();

    /**
     * CommandProto enum.
     * @name communicator_objects.CommandProto
     * @enum {number}
     * @property {number} STEP=0 STEP value
     * @property {number} RESET=1 RESET value
     * @property {number} QUIT=2 QUIT value
     */
    communicator_objects.CommandProto = (function() {
        var valuesById = {}, values = Object.create(valuesById);
        values[valuesById[0] = "STEP"] = 0;
        values[valuesById[1] = "RESET"] = 1;
        values[valuesById[2] = "QUIT"] = 2;
        return values;
    })();

    communicator_objects.CustomResetParametersProto = (function() {

        /**
         * Properties of a CustomResetParametersProto.
         * @memberof communicator_objects
         * @interface ICustomResetParametersProto
         */

        /**
         * Constructs a new CustomResetParametersProto.
         * @memberof communicator_objects
         * @classdesc Represents a CustomResetParametersProto.
         * @implements ICustomResetParametersProto
         * @constructor
         * @param {communicator_objects.ICustomResetParametersProto=} [properties] Properties to set
         */
        function CustomResetParametersProto(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * Creates a new CustomResetParametersProto instance using the specified properties.
         * @function create
         * @memberof communicator_objects.CustomResetParametersProto
         * @static
         * @param {communicator_objects.ICustomResetParametersProto=} [properties] Properties to set
         * @returns {communicator_objects.CustomResetParametersProto} CustomResetParametersProto instance
         */
        CustomResetParametersProto.create = function create(properties) {
            return new CustomResetParametersProto(properties);
        };

        /**
         * Encodes the specified CustomResetParametersProto message. Does not implicitly {@link communicator_objects.CustomResetParametersProto.verify|verify} messages.
         * @function encode
         * @memberof communicator_objects.CustomResetParametersProto
         * @static
         * @param {communicator_objects.ICustomResetParametersProto} message CustomResetParametersProto message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        CustomResetParametersProto.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            return writer;
        };

        /**
         * Encodes the specified CustomResetParametersProto message, length delimited. Does not implicitly {@link communicator_objects.CustomResetParametersProto.verify|verify} messages.
         * @function encodeDelimited
         * @memberof communicator_objects.CustomResetParametersProto
         * @static
         * @param {communicator_objects.ICustomResetParametersProto} message CustomResetParametersProto message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        CustomResetParametersProto.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a CustomResetParametersProto message from the specified reader or buffer.
         * @function decode
         * @memberof communicator_objects.CustomResetParametersProto
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {communicator_objects.CustomResetParametersProto} CustomResetParametersProto
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        CustomResetParametersProto.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.communicator_objects.CustomResetParametersProto();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a CustomResetParametersProto message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof communicator_objects.CustomResetParametersProto
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {communicator_objects.CustomResetParametersProto} CustomResetParametersProto
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        CustomResetParametersProto.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a CustomResetParametersProto message.
         * @function verify
         * @memberof communicator_objects.CustomResetParametersProto
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        CustomResetParametersProto.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            return null;
        };

        /**
         * Creates a CustomResetParametersProto message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof communicator_objects.CustomResetParametersProto
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {communicator_objects.CustomResetParametersProto} CustomResetParametersProto
         */
        CustomResetParametersProto.fromObject = function fromObject(object) {
            if (object instanceof $root.communicator_objects.CustomResetParametersProto)
                return object;
            return new $root.communicator_objects.CustomResetParametersProto();
        };

        /**
         * Creates a plain object from a CustomResetParametersProto message. Also converts values to other types if specified.
         * @function toObject
         * @memberof communicator_objects.CustomResetParametersProto
         * @static
         * @param {communicator_objects.CustomResetParametersProto} message CustomResetParametersProto
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        CustomResetParametersProto.toObject = function toObject() {
            return {};
        };

        /**
         * Converts this CustomResetParametersProto to JSON.
         * @function toJSON
         * @memberof communicator_objects.CustomResetParametersProto
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        CustomResetParametersProto.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return CustomResetParametersProto;
    })();

    communicator_objects.DemonstrationMetaProto = (function() {

        /**
         * Properties of a DemonstrationMetaProto.
         * @memberof communicator_objects
         * @interface IDemonstrationMetaProto
         * @property {number|null} [apiVersion] DemonstrationMetaProto apiVersion
         * @property {string|null} [demonstrationName] DemonstrationMetaProto demonstrationName
         * @property {number|null} [numberSteps] DemonstrationMetaProto numberSteps
         * @property {number|null} [numberEpisodes] DemonstrationMetaProto numberEpisodes
         * @property {number|null} [meanReward] DemonstrationMetaProto meanReward
         */

        /**
         * Constructs a new DemonstrationMetaProto.
         * @memberof communicator_objects
         * @classdesc Represents a DemonstrationMetaProto.
         * @implements IDemonstrationMetaProto
         * @constructor
         * @param {communicator_objects.IDemonstrationMetaProto=} [properties] Properties to set
         */
        function DemonstrationMetaProto(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * DemonstrationMetaProto apiVersion.
         * @member {number} apiVersion
         * @memberof communicator_objects.DemonstrationMetaProto
         * @instance
         */
        DemonstrationMetaProto.prototype.apiVersion = 0;

        /**
         * DemonstrationMetaProto demonstrationName.
         * @member {string} demonstrationName
         * @memberof communicator_objects.DemonstrationMetaProto
         * @instance
         */
        DemonstrationMetaProto.prototype.demonstrationName = "";

        /**
         * DemonstrationMetaProto numberSteps.
         * @member {number} numberSteps
         * @memberof communicator_objects.DemonstrationMetaProto
         * @instance
         */
        DemonstrationMetaProto.prototype.numberSteps = 0;

        /**
         * DemonstrationMetaProto numberEpisodes.
         * @member {number} numberEpisodes
         * @memberof communicator_objects.DemonstrationMetaProto
         * @instance
         */
        DemonstrationMetaProto.prototype.numberEpisodes = 0;

        /**
         * DemonstrationMetaProto meanReward.
         * @member {number} meanReward
         * @memberof communicator_objects.DemonstrationMetaProto
         * @instance
         */
        DemonstrationMetaProto.prototype.meanReward = 0;

        /**
         * Creates a new DemonstrationMetaProto instance using the specified properties.
         * @function create
         * @memberof communicator_objects.DemonstrationMetaProto
         * @static
         * @param {communicator_objects.IDemonstrationMetaProto=} [properties] Properties to set
         * @returns {communicator_objects.DemonstrationMetaProto} DemonstrationMetaProto instance
         */
        DemonstrationMetaProto.create = function create(properties) {
            return new DemonstrationMetaProto(properties);
        };

        /**
         * Encodes the specified DemonstrationMetaProto message. Does not implicitly {@link communicator_objects.DemonstrationMetaProto.verify|verify} messages.
         * @function encode
         * @memberof communicator_objects.DemonstrationMetaProto
         * @static
         * @param {communicator_objects.IDemonstrationMetaProto} message DemonstrationMetaProto message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        DemonstrationMetaProto.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.apiVersion != null && Object.hasOwnProperty.call(message, "apiVersion"))
                writer.uint32(/* id 1, wireType 0 =*/8).int32(message.apiVersion);
            if (message.demonstrationName != null && Object.hasOwnProperty.call(message, "demonstrationName"))
                writer.uint32(/* id 2, wireType 2 =*/18).string(message.demonstrationName);
            if (message.numberSteps != null && Object.hasOwnProperty.call(message, "numberSteps"))
                writer.uint32(/* id 3, wireType 0 =*/24).int32(message.numberSteps);
            if (message.numberEpisodes != null && Object.hasOwnProperty.call(message, "numberEpisodes"))
                writer.uint32(/* id 4, wireType 0 =*/32).int32(message.numberEpisodes);
            if (message.meanReward != null && Object.hasOwnProperty.call(message, "meanReward"))
                writer.uint32(/* id 5, wireType 5 =*/45).float(message.meanReward);
            return writer;
        };

        /**
         * Encodes the specified DemonstrationMetaProto message, length delimited. Does not implicitly {@link communicator_objects.DemonstrationMetaProto.verify|verify} messages.
         * @function encodeDelimited
         * @memberof communicator_objects.DemonstrationMetaProto
         * @static
         * @param {communicator_objects.IDemonstrationMetaProto} message DemonstrationMetaProto message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        DemonstrationMetaProto.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a DemonstrationMetaProto message from the specified reader or buffer.
         * @function decode
         * @memberof communicator_objects.DemonstrationMetaProto
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {communicator_objects.DemonstrationMetaProto} DemonstrationMetaProto
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        DemonstrationMetaProto.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.communicator_objects.DemonstrationMetaProto();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.apiVersion = reader.int32();
                    break;
                case 2:
                    message.demonstrationName = reader.string();
                    break;
                case 3:
                    message.numberSteps = reader.int32();
                    break;
                case 4:
                    message.numberEpisodes = reader.int32();
                    break;
                case 5:
                    message.meanReward = reader.float();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a DemonstrationMetaProto message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof communicator_objects.DemonstrationMetaProto
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {communicator_objects.DemonstrationMetaProto} DemonstrationMetaProto
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        DemonstrationMetaProto.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a DemonstrationMetaProto message.
         * @function verify
         * @memberof communicator_objects.DemonstrationMetaProto
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        DemonstrationMetaProto.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.apiVersion != null && message.hasOwnProperty("apiVersion"))
                if (!$util.isInteger(message.apiVersion))
                    return "apiVersion: integer expected";
            if (message.demonstrationName != null && message.hasOwnProperty("demonstrationName"))
                if (!$util.isString(message.demonstrationName))
                    return "demonstrationName: string expected";
            if (message.numberSteps != null && message.hasOwnProperty("numberSteps"))
                if (!$util.isInteger(message.numberSteps))
                    return "numberSteps: integer expected";
            if (message.numberEpisodes != null && message.hasOwnProperty("numberEpisodes"))
                if (!$util.isInteger(message.numberEpisodes))
                    return "numberEpisodes: integer expected";
            if (message.meanReward != null && message.hasOwnProperty("meanReward"))
                if (typeof message.meanReward !== "number")
                    return "meanReward: number expected";
            return null;
        };

        /**
         * Creates a DemonstrationMetaProto message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof communicator_objects.DemonstrationMetaProto
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {communicator_objects.DemonstrationMetaProto} DemonstrationMetaProto
         */
        DemonstrationMetaProto.fromObject = function fromObject(object) {
            if (object instanceof $root.communicator_objects.DemonstrationMetaProto)
                return object;
            var message = new $root.communicator_objects.DemonstrationMetaProto();
            if (object.apiVersion != null)
                message.apiVersion = object.apiVersion | 0;
            if (object.demonstrationName != null)
                message.demonstrationName = String(object.demonstrationName);
            if (object.numberSteps != null)
                message.numberSteps = object.numberSteps | 0;
            if (object.numberEpisodes != null)
                message.numberEpisodes = object.numberEpisodes | 0;
            if (object.meanReward != null)
                message.meanReward = Number(object.meanReward);
            return message;
        };

        /**
         * Creates a plain object from a DemonstrationMetaProto message. Also converts values to other types if specified.
         * @function toObject
         * @memberof communicator_objects.DemonstrationMetaProto
         * @static
         * @param {communicator_objects.DemonstrationMetaProto} message DemonstrationMetaProto
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        DemonstrationMetaProto.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                object.apiVersion = 0;
                object.demonstrationName = "";
                object.numberSteps = 0;
                object.numberEpisodes = 0;
                object.meanReward = 0;
            }
            if (message.apiVersion != null && message.hasOwnProperty("apiVersion"))
                object.apiVersion = message.apiVersion;
            if (message.demonstrationName != null && message.hasOwnProperty("demonstrationName"))
                object.demonstrationName = message.demonstrationName;
            if (message.numberSteps != null && message.hasOwnProperty("numberSteps"))
                object.numberSteps = message.numberSteps;
            if (message.numberEpisodes != null && message.hasOwnProperty("numberEpisodes"))
                object.numberEpisodes = message.numberEpisodes;
            if (message.meanReward != null && message.hasOwnProperty("meanReward"))
                object.meanReward = options.json && !isFinite(message.meanReward) ? String(message.meanReward) : message.meanReward;
            return object;
        };

        /**
         * Converts this DemonstrationMetaProto to JSON.
         * @function toJSON
         * @memberof communicator_objects.DemonstrationMetaProto
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        DemonstrationMetaProto.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return DemonstrationMetaProto;
    })();

    communicator_objects.EngineConfigurationProto = (function() {

        /**
         * Properties of an EngineConfigurationProto.
         * @memberof communicator_objects
         * @interface IEngineConfigurationProto
         * @property {number|null} [width] EngineConfigurationProto width
         * @property {number|null} [height] EngineConfigurationProto height
         * @property {number|null} [qualityLevel] EngineConfigurationProto qualityLevel
         * @property {number|null} [timeScale] EngineConfigurationProto timeScale
         * @property {number|null} [targetFrameRate] EngineConfigurationProto targetFrameRate
         * @property {boolean|null} [showMonitor] EngineConfigurationProto showMonitor
         */

        /**
         * Constructs a new EngineConfigurationProto.
         * @memberof communicator_objects
         * @classdesc Represents an EngineConfigurationProto.
         * @implements IEngineConfigurationProto
         * @constructor
         * @param {communicator_objects.IEngineConfigurationProto=} [properties] Properties to set
         */
        function EngineConfigurationProto(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * EngineConfigurationProto width.
         * @member {number} width
         * @memberof communicator_objects.EngineConfigurationProto
         * @instance
         */
        EngineConfigurationProto.prototype.width = 0;

        /**
         * EngineConfigurationProto height.
         * @member {number} height
         * @memberof communicator_objects.EngineConfigurationProto
         * @instance
         */
        EngineConfigurationProto.prototype.height = 0;

        /**
         * EngineConfigurationProto qualityLevel.
         * @member {number} qualityLevel
         * @memberof communicator_objects.EngineConfigurationProto
         * @instance
         */
        EngineConfigurationProto.prototype.qualityLevel = 0;

        /**
         * EngineConfigurationProto timeScale.
         * @member {number} timeScale
         * @memberof communicator_objects.EngineConfigurationProto
         * @instance
         */
        EngineConfigurationProto.prototype.timeScale = 0;

        /**
         * EngineConfigurationProto targetFrameRate.
         * @member {number} targetFrameRate
         * @memberof communicator_objects.EngineConfigurationProto
         * @instance
         */
        EngineConfigurationProto.prototype.targetFrameRate = 0;

        /**
         * EngineConfigurationProto showMonitor.
         * @member {boolean} showMonitor
         * @memberof communicator_objects.EngineConfigurationProto
         * @instance
         */
        EngineConfigurationProto.prototype.showMonitor = false;

        /**
         * Creates a new EngineConfigurationProto instance using the specified properties.
         * @function create
         * @memberof communicator_objects.EngineConfigurationProto
         * @static
         * @param {communicator_objects.IEngineConfigurationProto=} [properties] Properties to set
         * @returns {communicator_objects.EngineConfigurationProto} EngineConfigurationProto instance
         */
        EngineConfigurationProto.create = function create(properties) {
            return new EngineConfigurationProto(properties);
        };

        /**
         * Encodes the specified EngineConfigurationProto message. Does not implicitly {@link communicator_objects.EngineConfigurationProto.verify|verify} messages.
         * @function encode
         * @memberof communicator_objects.EngineConfigurationProto
         * @static
         * @param {communicator_objects.IEngineConfigurationProto} message EngineConfigurationProto message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        EngineConfigurationProto.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.width != null && Object.hasOwnProperty.call(message, "width"))
                writer.uint32(/* id 1, wireType 0 =*/8).int32(message.width);
            if (message.height != null && Object.hasOwnProperty.call(message, "height"))
                writer.uint32(/* id 2, wireType 0 =*/16).int32(message.height);
            if (message.qualityLevel != null && Object.hasOwnProperty.call(message, "qualityLevel"))
                writer.uint32(/* id 3, wireType 0 =*/24).int32(message.qualityLevel);
            if (message.timeScale != null && Object.hasOwnProperty.call(message, "timeScale"))
                writer.uint32(/* id 4, wireType 5 =*/37).float(message.timeScale);
            if (message.targetFrameRate != null && Object.hasOwnProperty.call(message, "targetFrameRate"))
                writer.uint32(/* id 5, wireType 0 =*/40).int32(message.targetFrameRate);
            if (message.showMonitor != null && Object.hasOwnProperty.call(message, "showMonitor"))
                writer.uint32(/* id 6, wireType 0 =*/48).bool(message.showMonitor);
            return writer;
        };

        /**
         * Encodes the specified EngineConfigurationProto message, length delimited. Does not implicitly {@link communicator_objects.EngineConfigurationProto.verify|verify} messages.
         * @function encodeDelimited
         * @memberof communicator_objects.EngineConfigurationProto
         * @static
         * @param {communicator_objects.IEngineConfigurationProto} message EngineConfigurationProto message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        EngineConfigurationProto.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes an EngineConfigurationProto message from the specified reader or buffer.
         * @function decode
         * @memberof communicator_objects.EngineConfigurationProto
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {communicator_objects.EngineConfigurationProto} EngineConfigurationProto
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        EngineConfigurationProto.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.communicator_objects.EngineConfigurationProto();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.width = reader.int32();
                    break;
                case 2:
                    message.height = reader.int32();
                    break;
                case 3:
                    message.qualityLevel = reader.int32();
                    break;
                case 4:
                    message.timeScale = reader.float();
                    break;
                case 5:
                    message.targetFrameRate = reader.int32();
                    break;
                case 6:
                    message.showMonitor = reader.bool();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes an EngineConfigurationProto message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof communicator_objects.EngineConfigurationProto
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {communicator_objects.EngineConfigurationProto} EngineConfigurationProto
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        EngineConfigurationProto.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies an EngineConfigurationProto message.
         * @function verify
         * @memberof communicator_objects.EngineConfigurationProto
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        EngineConfigurationProto.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.width != null && message.hasOwnProperty("width"))
                if (!$util.isInteger(message.width))
                    return "width: integer expected";
            if (message.height != null && message.hasOwnProperty("height"))
                if (!$util.isInteger(message.height))
                    return "height: integer expected";
            if (message.qualityLevel != null && message.hasOwnProperty("qualityLevel"))
                if (!$util.isInteger(message.qualityLevel))
                    return "qualityLevel: integer expected";
            if (message.timeScale != null && message.hasOwnProperty("timeScale"))
                if (typeof message.timeScale !== "number")
                    return "timeScale: number expected";
            if (message.targetFrameRate != null && message.hasOwnProperty("targetFrameRate"))
                if (!$util.isInteger(message.targetFrameRate))
                    return "targetFrameRate: integer expected";
            if (message.showMonitor != null && message.hasOwnProperty("showMonitor"))
                if (typeof message.showMonitor !== "boolean")
                    return "showMonitor: boolean expected";
            return null;
        };

        /**
         * Creates an EngineConfigurationProto message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof communicator_objects.EngineConfigurationProto
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {communicator_objects.EngineConfigurationProto} EngineConfigurationProto
         */
        EngineConfigurationProto.fromObject = function fromObject(object) {
            if (object instanceof $root.communicator_objects.EngineConfigurationProto)
                return object;
            var message = new $root.communicator_objects.EngineConfigurationProto();
            if (object.width != null)
                message.width = object.width | 0;
            if (object.height != null)
                message.height = object.height | 0;
            if (object.qualityLevel != null)
                message.qualityLevel = object.qualityLevel | 0;
            if (object.timeScale != null)
                message.timeScale = Number(object.timeScale);
            if (object.targetFrameRate != null)
                message.targetFrameRate = object.targetFrameRate | 0;
            if (object.showMonitor != null)
                message.showMonitor = Boolean(object.showMonitor);
            return message;
        };

        /**
         * Creates a plain object from an EngineConfigurationProto message. Also converts values to other types if specified.
         * @function toObject
         * @memberof communicator_objects.EngineConfigurationProto
         * @static
         * @param {communicator_objects.EngineConfigurationProto} message EngineConfigurationProto
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        EngineConfigurationProto.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                object.width = 0;
                object.height = 0;
                object.qualityLevel = 0;
                object.timeScale = 0;
                object.targetFrameRate = 0;
                object.showMonitor = false;
            }
            if (message.width != null && message.hasOwnProperty("width"))
                object.width = message.width;
            if (message.height != null && message.hasOwnProperty("height"))
                object.height = message.height;
            if (message.qualityLevel != null && message.hasOwnProperty("qualityLevel"))
                object.qualityLevel = message.qualityLevel;
            if (message.timeScale != null && message.hasOwnProperty("timeScale"))
                object.timeScale = options.json && !isFinite(message.timeScale) ? String(message.timeScale) : message.timeScale;
            if (message.targetFrameRate != null && message.hasOwnProperty("targetFrameRate"))
                object.targetFrameRate = message.targetFrameRate;
            if (message.showMonitor != null && message.hasOwnProperty("showMonitor"))
                object.showMonitor = message.showMonitor;
            return object;
        };

        /**
         * Converts this EngineConfigurationProto to JSON.
         * @function toJSON
         * @memberof communicator_objects.EngineConfigurationProto
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        EngineConfigurationProto.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return EngineConfigurationProto;
    })();

    communicator_objects.HeaderProto = (function() {

        /**
         * Properties of a HeaderProto.
         * @memberof communicator_objects
         * @interface IHeaderProto
         * @property {number|null} [status] HeaderProto status
         * @property {string|null} [message] HeaderProto message
         */

        /**
         * Constructs a new HeaderProto.
         * @memberof communicator_objects
         * @classdesc Represents a HeaderProto.
         * @implements IHeaderProto
         * @constructor
         * @param {communicator_objects.IHeaderProto=} [properties] Properties to set
         */
        function HeaderProto(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * HeaderProto status.
         * @member {number} status
         * @memberof communicator_objects.HeaderProto
         * @instance
         */
        HeaderProto.prototype.status = 0;

        /**
         * HeaderProto message.
         * @member {string} message
         * @memberof communicator_objects.HeaderProto
         * @instance
         */
        HeaderProto.prototype.message = "";

        /**
         * Creates a new HeaderProto instance using the specified properties.
         * @function create
         * @memberof communicator_objects.HeaderProto
         * @static
         * @param {communicator_objects.IHeaderProto=} [properties] Properties to set
         * @returns {communicator_objects.HeaderProto} HeaderProto instance
         */
        HeaderProto.create = function create(properties) {
            return new HeaderProto(properties);
        };

        /**
         * Encodes the specified HeaderProto message. Does not implicitly {@link communicator_objects.HeaderProto.verify|verify} messages.
         * @function encode
         * @memberof communicator_objects.HeaderProto
         * @static
         * @param {communicator_objects.IHeaderProto} message HeaderProto message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        HeaderProto.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.status != null && Object.hasOwnProperty.call(message, "status"))
                writer.uint32(/* id 1, wireType 0 =*/8).int32(message.status);
            if (message.message != null && Object.hasOwnProperty.call(message, "message"))
                writer.uint32(/* id 2, wireType 2 =*/18).string(message.message);
            return writer;
        };

        /**
         * Encodes the specified HeaderProto message, length delimited. Does not implicitly {@link communicator_objects.HeaderProto.verify|verify} messages.
         * @function encodeDelimited
         * @memberof communicator_objects.HeaderProto
         * @static
         * @param {communicator_objects.IHeaderProto} message HeaderProto message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        HeaderProto.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a HeaderProto message from the specified reader or buffer.
         * @function decode
         * @memberof communicator_objects.HeaderProto
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {communicator_objects.HeaderProto} HeaderProto
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        HeaderProto.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.communicator_objects.HeaderProto();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.status = reader.int32();
                    break;
                case 2:
                    message.message = reader.string();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a HeaderProto message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof communicator_objects.HeaderProto
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {communicator_objects.HeaderProto} HeaderProto
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        HeaderProto.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a HeaderProto message.
         * @function verify
         * @memberof communicator_objects.HeaderProto
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        HeaderProto.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.status != null && message.hasOwnProperty("status"))
                if (!$util.isInteger(message.status))
                    return "status: integer expected";
            if (message.message != null && message.hasOwnProperty("message"))
                if (!$util.isString(message.message))
                    return "message: string expected";
            return null;
        };

        /**
         * Creates a HeaderProto message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof communicator_objects.HeaderProto
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {communicator_objects.HeaderProto} HeaderProto
         */
        HeaderProto.fromObject = function fromObject(object) {
            if (object instanceof $root.communicator_objects.HeaderProto)
                return object;
            var message = new $root.communicator_objects.HeaderProto();
            if (object.status != null)
                message.status = object.status | 0;
            if (object.message != null)
                message.message = String(object.message);
            return message;
        };

        /**
         * Creates a plain object from a HeaderProto message. Also converts values to other types if specified.
         * @function toObject
         * @memberof communicator_objects.HeaderProto
         * @static
         * @param {communicator_objects.HeaderProto} message HeaderProto
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        HeaderProto.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                object.status = 0;
                object.message = "";
            }
            if (message.status != null && message.hasOwnProperty("status"))
                object.status = message.status;
            if (message.message != null && message.hasOwnProperty("message"))
                object.message = message.message;
            return object;
        };

        /**
         * Converts this HeaderProto to JSON.
         * @function toJSON
         * @memberof communicator_objects.HeaderProto
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        HeaderProto.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return HeaderProto;
    })();

    /**
     * CompressionTypeProto enum.
     * @name communicator_objects.CompressionTypeProto
     * @enum {number}
     * @property {number} NONE=0 NONE value
     * @property {number} PNG=1 PNG value
     */
    communicator_objects.CompressionTypeProto = (function() {
        var valuesById = {}, values = Object.create(valuesById);
        values[valuesById[0] = "NONE"] = 0;
        values[valuesById[1] = "PNG"] = 1;
        return values;
    })();

    /**
     * ObservationTypeProto enum.
     * @name communicator_objects.ObservationTypeProto
     * @enum {number}
     * @property {number} DEFAULT=0 DEFAULT value
     * @property {number} GOAL_SIGNAL=1 GOAL_SIGNAL value
     */
    communicator_objects.ObservationTypeProto = (function() {
        var valuesById = {}, values = Object.create(valuesById);
        values[valuesById[0] = "DEFAULT"] = 0;
        values[valuesById[1] = "GOAL_SIGNAL"] = 1;
        return values;
    })();

    communicator_objects.ObservationProto = (function() {

        /**
         * Properties of an ObservationProto.
         * @memberof communicator_objects
         * @interface IObservationProto
         * @property {Array.<number>|null} [shape] ObservationProto shape
         * @property {communicator_objects.CompressionTypeProto|null} [compressionType] ObservationProto compressionType
         * @property {Uint8Array|null} [compressedData] ObservationProto compressedData
         * @property {communicator_objects.ObservationProto.IFloatData|null} [floatData] ObservationProto floatData
         * @property {Array.<number>|null} [compressedChannelMapping] ObservationProto compressedChannelMapping
         * @property {Array.<number>|null} [dimensionProperties] ObservationProto dimensionProperties
         * @property {communicator_objects.ObservationTypeProto|null} [observationType] ObservationProto observationType
         * @property {string|null} [name] ObservationProto name
         */

        /**
         * Constructs a new ObservationProto.
         * @memberof communicator_objects
         * @classdesc Represents an ObservationProto.
         * @implements IObservationProto
         * @constructor
         * @param {communicator_objects.IObservationProto=} [properties] Properties to set
         */
        function ObservationProto(properties) {
            this.shape = [];
            this.compressedChannelMapping = [];
            this.dimensionProperties = [];
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * ObservationProto shape.
         * @member {Array.<number>} shape
         * @memberof communicator_objects.ObservationProto
         * @instance
         */
        ObservationProto.prototype.shape = $util.emptyArray;

        /**
         * ObservationProto compressionType.
         * @member {communicator_objects.CompressionTypeProto} compressionType
         * @memberof communicator_objects.ObservationProto
         * @instance
         */
        ObservationProto.prototype.compressionType = 0;

        /**
         * ObservationProto compressedData.
         * @member {Uint8Array|null|undefined} compressedData
         * @memberof communicator_objects.ObservationProto
         * @instance
         */
        ObservationProto.prototype.compressedData = null;

        /**
         * ObservationProto floatData.
         * @member {communicator_objects.ObservationProto.IFloatData|null|undefined} floatData
         * @memberof communicator_objects.ObservationProto
         * @instance
         */
        ObservationProto.prototype.floatData = null;

        /**
         * ObservationProto compressedChannelMapping.
         * @member {Array.<number>} compressedChannelMapping
         * @memberof communicator_objects.ObservationProto
         * @instance
         */
        ObservationProto.prototype.compressedChannelMapping = $util.emptyArray;

        /**
         * ObservationProto dimensionProperties.
         * @member {Array.<number>} dimensionProperties
         * @memberof communicator_objects.ObservationProto
         * @instance
         */
        ObservationProto.prototype.dimensionProperties = $util.emptyArray;

        /**
         * ObservationProto observationType.
         * @member {communicator_objects.ObservationTypeProto} observationType
         * @memberof communicator_objects.ObservationProto
         * @instance
         */
        ObservationProto.prototype.observationType = 0;

        /**
         * ObservationProto name.
         * @member {string} name
         * @memberof communicator_objects.ObservationProto
         * @instance
         */
        ObservationProto.prototype.name = "";

        // OneOf field names bound to virtual getters and setters
        var $oneOfFields;

        /**
         * ObservationProto observationData.
         * @member {"compressedData"|"floatData"|undefined} observationData
         * @memberof communicator_objects.ObservationProto
         * @instance
         */
        Object.defineProperty(ObservationProto.prototype, "observationData", {
            get: $util.oneOfGetter($oneOfFields = ["compressedData", "floatData"]),
            set: $util.oneOfSetter($oneOfFields)
        });

        /**
         * Creates a new ObservationProto instance using the specified properties.
         * @function create
         * @memberof communicator_objects.ObservationProto
         * @static
         * @param {communicator_objects.IObservationProto=} [properties] Properties to set
         * @returns {communicator_objects.ObservationProto} ObservationProto instance
         */
        ObservationProto.create = function create(properties) {
            return new ObservationProto(properties);
        };

        /**
         * Encodes the specified ObservationProto message. Does not implicitly {@link communicator_objects.ObservationProto.verify|verify} messages.
         * @function encode
         * @memberof communicator_objects.ObservationProto
         * @static
         * @param {communicator_objects.IObservationProto} message ObservationProto message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        ObservationProto.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.shape != null && message.shape.length) {
                writer.uint32(/* id 1, wireType 2 =*/10).fork();
                for (var i = 0; i < message.shape.length; ++i)
                    writer.int32(message.shape[i]);
                writer.ldelim();
            }
            if (message.compressionType != null && Object.hasOwnProperty.call(message, "compressionType"))
                writer.uint32(/* id 2, wireType 0 =*/16).int32(message.compressionType);
            if (message.compressedData != null && Object.hasOwnProperty.call(message, "compressedData"))
                writer.uint32(/* id 3, wireType 2 =*/26).bytes(message.compressedData);
            if (message.floatData != null && Object.hasOwnProperty.call(message, "floatData"))
                $root.communicator_objects.ObservationProto.FloatData.encode(message.floatData, writer.uint32(/* id 4, wireType 2 =*/34).fork()).ldelim();
            if (message.compressedChannelMapping != null && message.compressedChannelMapping.length) {
                writer.uint32(/* id 5, wireType 2 =*/42).fork();
                for (var i = 0; i < message.compressedChannelMapping.length; ++i)
                    writer.int32(message.compressedChannelMapping[i]);
                writer.ldelim();
            }
            if (message.dimensionProperties != null && message.dimensionProperties.length) {
                writer.uint32(/* id 6, wireType 2 =*/50).fork();
                for (var i = 0; i < message.dimensionProperties.length; ++i)
                    writer.int32(message.dimensionProperties[i]);
                writer.ldelim();
            }
            if (message.observationType != null && Object.hasOwnProperty.call(message, "observationType"))
                writer.uint32(/* id 7, wireType 0 =*/56).int32(message.observationType);
            if (message.name != null && Object.hasOwnProperty.call(message, "name"))
                writer.uint32(/* id 8, wireType 2 =*/66).string(message.name);
            return writer;
        };

        /**
         * Encodes the specified ObservationProto message, length delimited. Does not implicitly {@link communicator_objects.ObservationProto.verify|verify} messages.
         * @function encodeDelimited
         * @memberof communicator_objects.ObservationProto
         * @static
         * @param {communicator_objects.IObservationProto} message ObservationProto message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        ObservationProto.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes an ObservationProto message from the specified reader or buffer.
         * @function decode
         * @memberof communicator_objects.ObservationProto
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {communicator_objects.ObservationProto} ObservationProto
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        ObservationProto.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.communicator_objects.ObservationProto();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    if (!(message.shape && message.shape.length))
                        message.shape = [];
                    if ((tag & 7) === 2) {
                        var end2 = reader.uint32() + reader.pos;
                        while (reader.pos < end2)
                            message.shape.push(reader.int32());
                    } else
                        message.shape.push(reader.int32());
                    break;
                case 2:
                    message.compressionType = reader.int32();
                    break;
                case 3:
                    message.compressedData = reader.bytes();
                    break;
                case 4:
                    message.floatData = $root.communicator_objects.ObservationProto.FloatData.decode(reader, reader.uint32());
                    break;
                case 5:
                    if (!(message.compressedChannelMapping && message.compressedChannelMapping.length))
                        message.compressedChannelMapping = [];
                    if ((tag & 7) === 2) {
                        var end2 = reader.uint32() + reader.pos;
                        while (reader.pos < end2)
                            message.compressedChannelMapping.push(reader.int32());
                    } else
                        message.compressedChannelMapping.push(reader.int32());
                    break;
                case 6:
                    if (!(message.dimensionProperties && message.dimensionProperties.length))
                        message.dimensionProperties = [];
                    if ((tag & 7) === 2) {
                        var end2 = reader.uint32() + reader.pos;
                        while (reader.pos < end2)
                            message.dimensionProperties.push(reader.int32());
                    } else
                        message.dimensionProperties.push(reader.int32());
                    break;
                case 7:
                    message.observationType = reader.int32();
                    break;
                case 8:
                    message.name = reader.string();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes an ObservationProto message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof communicator_objects.ObservationProto
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {communicator_objects.ObservationProto} ObservationProto
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        ObservationProto.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies an ObservationProto message.
         * @function verify
         * @memberof communicator_objects.ObservationProto
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        ObservationProto.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            var properties = {};
            if (message.shape != null && message.hasOwnProperty("shape")) {
                if (!Array.isArray(message.shape))
                    return "shape: array expected";
                for (var i = 0; i < message.shape.length; ++i)
                    if (!$util.isInteger(message.shape[i]))
                        return "shape: integer[] expected";
            }
            if (message.compressionType != null && message.hasOwnProperty("compressionType"))
                switch (message.compressionType) {
                default:
                    return "compressionType: enum value expected";
                case 0:
                case 1:
                    break;
                }
            if (message.compressedData != null && message.hasOwnProperty("compressedData")) {
                properties.observationData = 1;
                if (!(message.compressedData && typeof message.compressedData.length === "number" || $util.isString(message.compressedData)))
                    return "compressedData: buffer expected";
            }
            if (message.floatData != null && message.hasOwnProperty("floatData")) {
                if (properties.observationData === 1)
                    return "observationData: multiple values";
                properties.observationData = 1;
                {
                    var error = $root.communicator_objects.ObservationProto.FloatData.verify(message.floatData);
                    if (error)
                        return "floatData." + error;
                }
            }
            if (message.compressedChannelMapping != null && message.hasOwnProperty("compressedChannelMapping")) {
                if (!Array.isArray(message.compressedChannelMapping))
                    return "compressedChannelMapping: array expected";
                for (var i = 0; i < message.compressedChannelMapping.length; ++i)
                    if (!$util.isInteger(message.compressedChannelMapping[i]))
                        return "compressedChannelMapping: integer[] expected";
            }
            if (message.dimensionProperties != null && message.hasOwnProperty("dimensionProperties")) {
                if (!Array.isArray(message.dimensionProperties))
                    return "dimensionProperties: array expected";
                for (var i = 0; i < message.dimensionProperties.length; ++i)
                    if (!$util.isInteger(message.dimensionProperties[i]))
                        return "dimensionProperties: integer[] expected";
            }
            if (message.observationType != null && message.hasOwnProperty("observationType"))
                switch (message.observationType) {
                default:
                    return "observationType: enum value expected";
                case 0:
                case 1:
                    break;
                }
            if (message.name != null && message.hasOwnProperty("name"))
                if (!$util.isString(message.name))
                    return "name: string expected";
            return null;
        };

        /**
         * Creates an ObservationProto message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof communicator_objects.ObservationProto
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {communicator_objects.ObservationProto} ObservationProto
         */
        ObservationProto.fromObject = function fromObject(object) {
            if (object instanceof $root.communicator_objects.ObservationProto)
                return object;
            var message = new $root.communicator_objects.ObservationProto();
            if (object.shape) {
                if (!Array.isArray(object.shape))
                    throw TypeError(".communicator_objects.ObservationProto.shape: array expected");
                message.shape = [];
                for (var i = 0; i < object.shape.length; ++i)
                    message.shape[i] = object.shape[i] | 0;
            }
            switch (object.compressionType) {
            case "NONE":
            case 0:
                message.compressionType = 0;
                break;
            case "PNG":
            case 1:
                message.compressionType = 1;
                break;
            }
            if (object.compressedData != null)
                if (typeof object.compressedData === "string")
                    $util.base64.decode(object.compressedData, message.compressedData = $util.newBuffer($util.base64.length(object.compressedData)), 0);
                else if (object.compressedData.length)
                    message.compressedData = object.compressedData;
            if (object.floatData != null) {
                if (typeof object.floatData !== "object")
                    throw TypeError(".communicator_objects.ObservationProto.floatData: object expected");
                message.floatData = $root.communicator_objects.ObservationProto.FloatData.fromObject(object.floatData);
            }
            if (object.compressedChannelMapping) {
                if (!Array.isArray(object.compressedChannelMapping))
                    throw TypeError(".communicator_objects.ObservationProto.compressedChannelMapping: array expected");
                message.compressedChannelMapping = [];
                for (var i = 0; i < object.compressedChannelMapping.length; ++i)
                    message.compressedChannelMapping[i] = object.compressedChannelMapping[i] | 0;
            }
            if (object.dimensionProperties) {
                if (!Array.isArray(object.dimensionProperties))
                    throw TypeError(".communicator_objects.ObservationProto.dimensionProperties: array expected");
                message.dimensionProperties = [];
                for (var i = 0; i < object.dimensionProperties.length; ++i)
                    message.dimensionProperties[i] = object.dimensionProperties[i] | 0;
            }
            switch (object.observationType) {
            case "DEFAULT":
            case 0:
                message.observationType = 0;
                break;
            case "GOAL_SIGNAL":
            case 1:
                message.observationType = 1;
                break;
            }
            if (object.name != null)
                message.name = String(object.name);
            return message;
        };

        /**
         * Creates a plain object from an ObservationProto message. Also converts values to other types if specified.
         * @function toObject
         * @memberof communicator_objects.ObservationProto
         * @static
         * @param {communicator_objects.ObservationProto} message ObservationProto
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        ObservationProto.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.arrays || options.defaults) {
                object.shape = [];
                object.compressedChannelMapping = [];
                object.dimensionProperties = [];
            }
            if (options.defaults) {
                object.compressionType = options.enums === String ? "NONE" : 0;
                object.observationType = options.enums === String ? "DEFAULT" : 0;
                object.name = "";
            }
            if (message.shape && message.shape.length) {
                object.shape = [];
                for (var j = 0; j < message.shape.length; ++j)
                    object.shape[j] = message.shape[j];
            }
            if (message.compressionType != null && message.hasOwnProperty("compressionType"))
                object.compressionType = options.enums === String ? $root.communicator_objects.CompressionTypeProto[message.compressionType] : message.compressionType;
            if (message.compressedData != null && message.hasOwnProperty("compressedData")) {
                object.compressedData = options.bytes === String ? $util.base64.encode(message.compressedData, 0, message.compressedData.length) : options.bytes === Array ? Array.prototype.slice.call(message.compressedData) : message.compressedData;
                if (options.oneofs)
                    object.observationData = "compressedData";
            }
            if (message.floatData != null && message.hasOwnProperty("floatData")) {
                object.floatData = $root.communicator_objects.ObservationProto.FloatData.toObject(message.floatData, options);
                if (options.oneofs)
                    object.observationData = "floatData";
            }
            if (message.compressedChannelMapping && message.compressedChannelMapping.length) {
                object.compressedChannelMapping = [];
                for (var j = 0; j < message.compressedChannelMapping.length; ++j)
                    object.compressedChannelMapping[j] = message.compressedChannelMapping[j];
            }
            if (message.dimensionProperties && message.dimensionProperties.length) {
                object.dimensionProperties = [];
                for (var j = 0; j < message.dimensionProperties.length; ++j)
                    object.dimensionProperties[j] = message.dimensionProperties[j];
            }
            if (message.observationType != null && message.hasOwnProperty("observationType"))
                object.observationType = options.enums === String ? $root.communicator_objects.ObservationTypeProto[message.observationType] : message.observationType;
            if (message.name != null && message.hasOwnProperty("name"))
                object.name = message.name;
            return object;
        };

        /**
         * Converts this ObservationProto to JSON.
         * @function toJSON
         * @memberof communicator_objects.ObservationProto
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        ObservationProto.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        ObservationProto.FloatData = (function() {

            /**
             * Properties of a FloatData.
             * @memberof communicator_objects.ObservationProto
             * @interface IFloatData
             * @property {Array.<number>|null} [data] FloatData data
             */

            /**
             * Constructs a new FloatData.
             * @memberof communicator_objects.ObservationProto
             * @classdesc Represents a FloatData.
             * @implements IFloatData
             * @constructor
             * @param {communicator_objects.ObservationProto.IFloatData=} [properties] Properties to set
             */
            function FloatData(properties) {
                this.data = [];
                if (properties)
                    for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                        if (properties[keys[i]] != null)
                            this[keys[i]] = properties[keys[i]];
            }

            /**
             * FloatData data.
             * @member {Array.<number>} data
             * @memberof communicator_objects.ObservationProto.FloatData
             * @instance
             */
            FloatData.prototype.data = $util.emptyArray;

            /**
             * Creates a new FloatData instance using the specified properties.
             * @function create
             * @memberof communicator_objects.ObservationProto.FloatData
             * @static
             * @param {communicator_objects.ObservationProto.IFloatData=} [properties] Properties to set
             * @returns {communicator_objects.ObservationProto.FloatData} FloatData instance
             */
            FloatData.create = function create(properties) {
                return new FloatData(properties);
            };

            /**
             * Encodes the specified FloatData message. Does not implicitly {@link communicator_objects.ObservationProto.FloatData.verify|verify} messages.
             * @function encode
             * @memberof communicator_objects.ObservationProto.FloatData
             * @static
             * @param {communicator_objects.ObservationProto.IFloatData} message FloatData message or plain object to encode
             * @param {$protobuf.Writer} [writer] Writer to encode to
             * @returns {$protobuf.Writer} Writer
             */
            FloatData.encode = function encode(message, writer) {
                if (!writer)
                    writer = $Writer.create();
                if (message.data != null && message.data.length) {
                    writer.uint32(/* id 1, wireType 2 =*/10).fork();
                    for (var i = 0; i < message.data.length; ++i)
                        writer.float(message.data[i]);
                    writer.ldelim();
                }
                return writer;
            };

            /**
             * Encodes the specified FloatData message, length delimited. Does not implicitly {@link communicator_objects.ObservationProto.FloatData.verify|verify} messages.
             * @function encodeDelimited
             * @memberof communicator_objects.ObservationProto.FloatData
             * @static
             * @param {communicator_objects.ObservationProto.IFloatData} message FloatData message or plain object to encode
             * @param {$protobuf.Writer} [writer] Writer to encode to
             * @returns {$protobuf.Writer} Writer
             */
            FloatData.encodeDelimited = function encodeDelimited(message, writer) {
                return this.encode(message, writer).ldelim();
            };

            /**
             * Decodes a FloatData message from the specified reader or buffer.
             * @function decode
             * @memberof communicator_objects.ObservationProto.FloatData
             * @static
             * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
             * @param {number} [length] Message length if known beforehand
             * @returns {communicator_objects.ObservationProto.FloatData} FloatData
             * @throws {Error} If the payload is not a reader or valid buffer
             * @throws {$protobuf.util.ProtocolError} If required fields are missing
             */
            FloatData.decode = function decode(reader, length) {
                if (!(reader instanceof $Reader))
                    reader = $Reader.create(reader);
                var end = length === undefined ? reader.len : reader.pos + length, message = new $root.communicator_objects.ObservationProto.FloatData();
                while (reader.pos < end) {
                    var tag = reader.uint32();
                    switch (tag >>> 3) {
                    case 1:
                        if (!(message.data && message.data.length))
                            message.data = [];
                        if ((tag & 7) === 2) {
                            var end2 = reader.uint32() + reader.pos;
                            while (reader.pos < end2)
                                message.data.push(reader.float());
                        } else
                            message.data.push(reader.float());
                        break;
                    default:
                        reader.skipType(tag & 7);
                        break;
                    }
                }
                return message;
            };

            /**
             * Decodes a FloatData message from the specified reader or buffer, length delimited.
             * @function decodeDelimited
             * @memberof communicator_objects.ObservationProto.FloatData
             * @static
             * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
             * @returns {communicator_objects.ObservationProto.FloatData} FloatData
             * @throws {Error} If the payload is not a reader or valid buffer
             * @throws {$protobuf.util.ProtocolError} If required fields are missing
             */
            FloatData.decodeDelimited = function decodeDelimited(reader) {
                if (!(reader instanceof $Reader))
                    reader = new $Reader(reader);
                return this.decode(reader, reader.uint32());
            };

            /**
             * Verifies a FloatData message.
             * @function verify
             * @memberof communicator_objects.ObservationProto.FloatData
             * @static
             * @param {Object.<string,*>} message Plain object to verify
             * @returns {string|null} `null` if valid, otherwise the reason why it is not
             */
            FloatData.verify = function verify(message) {
                if (typeof message !== "object" || message === null)
                    return "object expected";
                if (message.data != null && message.hasOwnProperty("data")) {
                    if (!Array.isArray(message.data))
                        return "data: array expected";
                    for (var i = 0; i < message.data.length; ++i)
                        if (typeof message.data[i] !== "number")
                            return "data: number[] expected";
                }
                return null;
            };

            /**
             * Creates a FloatData message from a plain object. Also converts values to their respective internal types.
             * @function fromObject
             * @memberof communicator_objects.ObservationProto.FloatData
             * @static
             * @param {Object.<string,*>} object Plain object
             * @returns {communicator_objects.ObservationProto.FloatData} FloatData
             */
            FloatData.fromObject = function fromObject(object) {
                if (object instanceof $root.communicator_objects.ObservationProto.FloatData)
                    return object;
                var message = new $root.communicator_objects.ObservationProto.FloatData();
                if (object.data) {
                    if (!Array.isArray(object.data))
                        throw TypeError(".communicator_objects.ObservationProto.FloatData.data: array expected");
                    message.data = [];
                    for (var i = 0; i < object.data.length; ++i)
                        message.data[i] = Number(object.data[i]);
                }
                return message;
            };

            /**
             * Creates a plain object from a FloatData message. Also converts values to other types if specified.
             * @function toObject
             * @memberof communicator_objects.ObservationProto.FloatData
             * @static
             * @param {communicator_objects.ObservationProto.FloatData} message FloatData
             * @param {$protobuf.IConversionOptions} [options] Conversion options
             * @returns {Object.<string,*>} Plain object
             */
            FloatData.toObject = function toObject(message, options) {
                if (!options)
                    options = {};
                var object = {};
                if (options.arrays || options.defaults)
                    object.data = [];
                if (message.data && message.data.length) {
                    object.data = [];
                    for (var j = 0; j < message.data.length; ++j)
                        object.data[j] = options.json && !isFinite(message.data[j]) ? String(message.data[j]) : message.data[j];
                }
                return object;
            };

            /**
             * Converts this FloatData to JSON.
             * @function toJSON
             * @memberof communicator_objects.ObservationProto.FloatData
             * @instance
             * @returns {Object.<string,*>} JSON object
             */
            FloatData.prototype.toJSON = function toJSON() {
                return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
            };

            return FloatData;
        })();

        return ObservationProto;
    })();

    /**
     * SpaceTypeProto enum.
     * @name communicator_objects.SpaceTypeProto
     * @enum {number}
     * @property {number} discrete=0 discrete value
     * @property {number} continuous=1 continuous value
     */
    communicator_objects.SpaceTypeProto = (function() {
        var valuesById = {}, values = Object.create(valuesById);
        values[valuesById[0] = "discrete"] = 0;
        values[valuesById[1] = "continuous"] = 1;
        return values;
    })();

    communicator_objects.TrainingEnvironmentInitialized = (function() {

        /**
         * Properties of a TrainingEnvironmentInitialized.
         * @memberof communicator_objects
         * @interface ITrainingEnvironmentInitialized
         * @property {string|null} [mlagentsVersion] TrainingEnvironmentInitialized mlagentsVersion
         * @property {string|null} [mlagentsEnvsVersion] TrainingEnvironmentInitialized mlagentsEnvsVersion
         * @property {string|null} [pythonVersion] TrainingEnvironmentInitialized pythonVersion
         * @property {string|null} [torchVersion] TrainingEnvironmentInitialized torchVersion
         * @property {string|null} [torchDeviceType] TrainingEnvironmentInitialized torchDeviceType
         * @property {number|null} [numEnvs] TrainingEnvironmentInitialized numEnvs
         * @property {number|null} [numEnvironmentParameters] TrainingEnvironmentInitialized numEnvironmentParameters
         * @property {string|null} [runOptions] TrainingEnvironmentInitialized runOptions
         */

        /**
         * Constructs a new TrainingEnvironmentInitialized.
         * @memberof communicator_objects
         * @classdesc Represents a TrainingEnvironmentInitialized.
         * @implements ITrainingEnvironmentInitialized
         * @constructor
         * @param {communicator_objects.ITrainingEnvironmentInitialized=} [properties] Properties to set
         */
        function TrainingEnvironmentInitialized(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * TrainingEnvironmentInitialized mlagentsVersion.
         * @member {string} mlagentsVersion
         * @memberof communicator_objects.TrainingEnvironmentInitialized
         * @instance
         */
        TrainingEnvironmentInitialized.prototype.mlagentsVersion = "";

        /**
         * TrainingEnvironmentInitialized mlagentsEnvsVersion.
         * @member {string} mlagentsEnvsVersion
         * @memberof communicator_objects.TrainingEnvironmentInitialized
         * @instance
         */
        TrainingEnvironmentInitialized.prototype.mlagentsEnvsVersion = "";

        /**
         * TrainingEnvironmentInitialized pythonVersion.
         * @member {string} pythonVersion
         * @memberof communicator_objects.TrainingEnvironmentInitialized
         * @instance
         */
        TrainingEnvironmentInitialized.prototype.pythonVersion = "";

        /**
         * TrainingEnvironmentInitialized torchVersion.
         * @member {string} torchVersion
         * @memberof communicator_objects.TrainingEnvironmentInitialized
         * @instance
         */
        TrainingEnvironmentInitialized.prototype.torchVersion = "";

        /**
         * TrainingEnvironmentInitialized torchDeviceType.
         * @member {string} torchDeviceType
         * @memberof communicator_objects.TrainingEnvironmentInitialized
         * @instance
         */
        TrainingEnvironmentInitialized.prototype.torchDeviceType = "";

        /**
         * TrainingEnvironmentInitialized numEnvs.
         * @member {number} numEnvs
         * @memberof communicator_objects.TrainingEnvironmentInitialized
         * @instance
         */
        TrainingEnvironmentInitialized.prototype.numEnvs = 0;

        /**
         * TrainingEnvironmentInitialized numEnvironmentParameters.
         * @member {number} numEnvironmentParameters
         * @memberof communicator_objects.TrainingEnvironmentInitialized
         * @instance
         */
        TrainingEnvironmentInitialized.prototype.numEnvironmentParameters = 0;

        /**
         * TrainingEnvironmentInitialized runOptions.
         * @member {string} runOptions
         * @memberof communicator_objects.TrainingEnvironmentInitialized
         * @instance
         */
        TrainingEnvironmentInitialized.prototype.runOptions = "";

        /**
         * Creates a new TrainingEnvironmentInitialized instance using the specified properties.
         * @function create
         * @memberof communicator_objects.TrainingEnvironmentInitialized
         * @static
         * @param {communicator_objects.ITrainingEnvironmentInitialized=} [properties] Properties to set
         * @returns {communicator_objects.TrainingEnvironmentInitialized} TrainingEnvironmentInitialized instance
         */
        TrainingEnvironmentInitialized.create = function create(properties) {
            return new TrainingEnvironmentInitialized(properties);
        };

        /**
         * Encodes the specified TrainingEnvironmentInitialized message. Does not implicitly {@link communicator_objects.TrainingEnvironmentInitialized.verify|verify} messages.
         * @function encode
         * @memberof communicator_objects.TrainingEnvironmentInitialized
         * @static
         * @param {communicator_objects.ITrainingEnvironmentInitialized} message TrainingEnvironmentInitialized message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        TrainingEnvironmentInitialized.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.mlagentsVersion != null && Object.hasOwnProperty.call(message, "mlagentsVersion"))
                writer.uint32(/* id 1, wireType 2 =*/10).string(message.mlagentsVersion);
            if (message.mlagentsEnvsVersion != null && Object.hasOwnProperty.call(message, "mlagentsEnvsVersion"))
                writer.uint32(/* id 2, wireType 2 =*/18).string(message.mlagentsEnvsVersion);
            if (message.pythonVersion != null && Object.hasOwnProperty.call(message, "pythonVersion"))
                writer.uint32(/* id 3, wireType 2 =*/26).string(message.pythonVersion);
            if (message.torchVersion != null && Object.hasOwnProperty.call(message, "torchVersion"))
                writer.uint32(/* id 4, wireType 2 =*/34).string(message.torchVersion);
            if (message.torchDeviceType != null && Object.hasOwnProperty.call(message, "torchDeviceType"))
                writer.uint32(/* id 5, wireType 2 =*/42).string(message.torchDeviceType);
            if (message.numEnvs != null && Object.hasOwnProperty.call(message, "numEnvs"))
                writer.uint32(/* id 6, wireType 0 =*/48).int32(message.numEnvs);
            if (message.numEnvironmentParameters != null && Object.hasOwnProperty.call(message, "numEnvironmentParameters"))
                writer.uint32(/* id 7, wireType 0 =*/56).int32(message.numEnvironmentParameters);
            if (message.runOptions != null && Object.hasOwnProperty.call(message, "runOptions"))
                writer.uint32(/* id 8, wireType 2 =*/66).string(message.runOptions);
            return writer;
        };

        /**
         * Encodes the specified TrainingEnvironmentInitialized message, length delimited. Does not implicitly {@link communicator_objects.TrainingEnvironmentInitialized.verify|verify} messages.
         * @function encodeDelimited
         * @memberof communicator_objects.TrainingEnvironmentInitialized
         * @static
         * @param {communicator_objects.ITrainingEnvironmentInitialized} message TrainingEnvironmentInitialized message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        TrainingEnvironmentInitialized.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a TrainingEnvironmentInitialized message from the specified reader or buffer.
         * @function decode
         * @memberof communicator_objects.TrainingEnvironmentInitialized
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {communicator_objects.TrainingEnvironmentInitialized} TrainingEnvironmentInitialized
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        TrainingEnvironmentInitialized.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.communicator_objects.TrainingEnvironmentInitialized();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.mlagentsVersion = reader.string();
                    break;
                case 2:
                    message.mlagentsEnvsVersion = reader.string();
                    break;
                case 3:
                    message.pythonVersion = reader.string();
                    break;
                case 4:
                    message.torchVersion = reader.string();
                    break;
                case 5:
                    message.torchDeviceType = reader.string();
                    break;
                case 6:
                    message.numEnvs = reader.int32();
                    break;
                case 7:
                    message.numEnvironmentParameters = reader.int32();
                    break;
                case 8:
                    message.runOptions = reader.string();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a TrainingEnvironmentInitialized message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof communicator_objects.TrainingEnvironmentInitialized
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {communicator_objects.TrainingEnvironmentInitialized} TrainingEnvironmentInitialized
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        TrainingEnvironmentInitialized.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a TrainingEnvironmentInitialized message.
         * @function verify
         * @memberof communicator_objects.TrainingEnvironmentInitialized
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        TrainingEnvironmentInitialized.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.mlagentsVersion != null && message.hasOwnProperty("mlagentsVersion"))
                if (!$util.isString(message.mlagentsVersion))
                    return "mlagentsVersion: string expected";
            if (message.mlagentsEnvsVersion != null && message.hasOwnProperty("mlagentsEnvsVersion"))
                if (!$util.isString(message.mlagentsEnvsVersion))
                    return "mlagentsEnvsVersion: string expected";
            if (message.pythonVersion != null && message.hasOwnProperty("pythonVersion"))
                if (!$util.isString(message.pythonVersion))
                    return "pythonVersion: string expected";
            if (message.torchVersion != null && message.hasOwnProperty("torchVersion"))
                if (!$util.isString(message.torchVersion))
                    return "torchVersion: string expected";
            if (message.torchDeviceType != null && message.hasOwnProperty("torchDeviceType"))
                if (!$util.isString(message.torchDeviceType))
                    return "torchDeviceType: string expected";
            if (message.numEnvs != null && message.hasOwnProperty("numEnvs"))
                if (!$util.isInteger(message.numEnvs))
                    return "numEnvs: integer expected";
            if (message.numEnvironmentParameters != null && message.hasOwnProperty("numEnvironmentParameters"))
                if (!$util.isInteger(message.numEnvironmentParameters))
                    return "numEnvironmentParameters: integer expected";
            if (message.runOptions != null && message.hasOwnProperty("runOptions"))
                if (!$util.isString(message.runOptions))
                    return "runOptions: string expected";
            return null;
        };

        /**
         * Creates a TrainingEnvironmentInitialized message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof communicator_objects.TrainingEnvironmentInitialized
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {communicator_objects.TrainingEnvironmentInitialized} TrainingEnvironmentInitialized
         */
        TrainingEnvironmentInitialized.fromObject = function fromObject(object) {
            if (object instanceof $root.communicator_objects.TrainingEnvironmentInitialized)
                return object;
            var message = new $root.communicator_objects.TrainingEnvironmentInitialized();
            if (object.mlagentsVersion != null)
                message.mlagentsVersion = String(object.mlagentsVersion);
            if (object.mlagentsEnvsVersion != null)
                message.mlagentsEnvsVersion = String(object.mlagentsEnvsVersion);
            if (object.pythonVersion != null)
                message.pythonVersion = String(object.pythonVersion);
            if (object.torchVersion != null)
                message.torchVersion = String(object.torchVersion);
            if (object.torchDeviceType != null)
                message.torchDeviceType = String(object.torchDeviceType);
            if (object.numEnvs != null)
                message.numEnvs = object.numEnvs | 0;
            if (object.numEnvironmentParameters != null)
                message.numEnvironmentParameters = object.numEnvironmentParameters | 0;
            if (object.runOptions != null)
                message.runOptions = String(object.runOptions);
            return message;
        };

        /**
         * Creates a plain object from a TrainingEnvironmentInitialized message. Also converts values to other types if specified.
         * @function toObject
         * @memberof communicator_objects.TrainingEnvironmentInitialized
         * @static
         * @param {communicator_objects.TrainingEnvironmentInitialized} message TrainingEnvironmentInitialized
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        TrainingEnvironmentInitialized.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                object.mlagentsVersion = "";
                object.mlagentsEnvsVersion = "";
                object.pythonVersion = "";
                object.torchVersion = "";
                object.torchDeviceType = "";
                object.numEnvs = 0;
                object.numEnvironmentParameters = 0;
                object.runOptions = "";
            }
            if (message.mlagentsVersion != null && message.hasOwnProperty("mlagentsVersion"))
                object.mlagentsVersion = message.mlagentsVersion;
            if (message.mlagentsEnvsVersion != null && message.hasOwnProperty("mlagentsEnvsVersion"))
                object.mlagentsEnvsVersion = message.mlagentsEnvsVersion;
            if (message.pythonVersion != null && message.hasOwnProperty("pythonVersion"))
                object.pythonVersion = message.pythonVersion;
            if (message.torchVersion != null && message.hasOwnProperty("torchVersion"))
                object.torchVersion = message.torchVersion;
            if (message.torchDeviceType != null && message.hasOwnProperty("torchDeviceType"))
                object.torchDeviceType = message.torchDeviceType;
            if (message.numEnvs != null && message.hasOwnProperty("numEnvs"))
                object.numEnvs = message.numEnvs;
            if (message.numEnvironmentParameters != null && message.hasOwnProperty("numEnvironmentParameters"))
                object.numEnvironmentParameters = message.numEnvironmentParameters;
            if (message.runOptions != null && message.hasOwnProperty("runOptions"))
                object.runOptions = message.runOptions;
            return object;
        };

        /**
         * Converts this TrainingEnvironmentInitialized to JSON.
         * @function toJSON
         * @memberof communicator_objects.TrainingEnvironmentInitialized
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        TrainingEnvironmentInitialized.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return TrainingEnvironmentInitialized;
    })();

    communicator_objects.TrainingBehaviorInitialized = (function() {

        /**
         * Properties of a TrainingBehaviorInitialized.
         * @memberof communicator_objects
         * @interface ITrainingBehaviorInitialized
         * @property {string|null} [behaviorName] TrainingBehaviorInitialized behaviorName
         * @property {string|null} [trainerType] TrainingBehaviorInitialized trainerType
         * @property {boolean|null} [extrinsicRewardEnabled] TrainingBehaviorInitialized extrinsicRewardEnabled
         * @property {boolean|null} [gailRewardEnabled] TrainingBehaviorInitialized gailRewardEnabled
         * @property {boolean|null} [curiosityRewardEnabled] TrainingBehaviorInitialized curiosityRewardEnabled
         * @property {boolean|null} [rndRewardEnabled] TrainingBehaviorInitialized rndRewardEnabled
         * @property {boolean|null} [behavioralCloningEnabled] TrainingBehaviorInitialized behavioralCloningEnabled
         * @property {boolean|null} [recurrentEnabled] TrainingBehaviorInitialized recurrentEnabled
         * @property {string|null} [visualEncoder] TrainingBehaviorInitialized visualEncoder
         * @property {number|null} [numNetworkLayers] TrainingBehaviorInitialized numNetworkLayers
         * @property {number|null} [numNetworkHiddenUnits] TrainingBehaviorInitialized numNetworkHiddenUnits
         * @property {boolean|null} [trainerThreaded] TrainingBehaviorInitialized trainerThreaded
         * @property {boolean|null} [selfPlayEnabled] TrainingBehaviorInitialized selfPlayEnabled
         * @property {boolean|null} [curriculumEnabled] TrainingBehaviorInitialized curriculumEnabled
         * @property {string|null} [config] TrainingBehaviorInitialized config
         */

        /**
         * Constructs a new TrainingBehaviorInitialized.
         * @memberof communicator_objects
         * @classdesc Represents a TrainingBehaviorInitialized.
         * @implements ITrainingBehaviorInitialized
         * @constructor
         * @param {communicator_objects.ITrainingBehaviorInitialized=} [properties] Properties to set
         */
        function TrainingBehaviorInitialized(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * TrainingBehaviorInitialized behaviorName.
         * @member {string} behaviorName
         * @memberof communicator_objects.TrainingBehaviorInitialized
         * @instance
         */
        TrainingBehaviorInitialized.prototype.behaviorName = "";

        /**
         * TrainingBehaviorInitialized trainerType.
         * @member {string} trainerType
         * @memberof communicator_objects.TrainingBehaviorInitialized
         * @instance
         */
        TrainingBehaviorInitialized.prototype.trainerType = "";

        /**
         * TrainingBehaviorInitialized extrinsicRewardEnabled.
         * @member {boolean} extrinsicRewardEnabled
         * @memberof communicator_objects.TrainingBehaviorInitialized
         * @instance
         */
        TrainingBehaviorInitialized.prototype.extrinsicRewardEnabled = false;

        /**
         * TrainingBehaviorInitialized gailRewardEnabled.
         * @member {boolean} gailRewardEnabled
         * @memberof communicator_objects.TrainingBehaviorInitialized
         * @instance
         */
        TrainingBehaviorInitialized.prototype.gailRewardEnabled = false;

        /**
         * TrainingBehaviorInitialized curiosityRewardEnabled.
         * @member {boolean} curiosityRewardEnabled
         * @memberof communicator_objects.TrainingBehaviorInitialized
         * @instance
         */
        TrainingBehaviorInitialized.prototype.curiosityRewardEnabled = false;

        /**
         * TrainingBehaviorInitialized rndRewardEnabled.
         * @member {boolean} rndRewardEnabled
         * @memberof communicator_objects.TrainingBehaviorInitialized
         * @instance
         */
        TrainingBehaviorInitialized.prototype.rndRewardEnabled = false;

        /**
         * TrainingBehaviorInitialized behavioralCloningEnabled.
         * @member {boolean} behavioralCloningEnabled
         * @memberof communicator_objects.TrainingBehaviorInitialized
         * @instance
         */
        TrainingBehaviorInitialized.prototype.behavioralCloningEnabled = false;

        /**
         * TrainingBehaviorInitialized recurrentEnabled.
         * @member {boolean} recurrentEnabled
         * @memberof communicator_objects.TrainingBehaviorInitialized
         * @instance
         */
        TrainingBehaviorInitialized.prototype.recurrentEnabled = false;

        /**
         * TrainingBehaviorInitialized visualEncoder.
         * @member {string} visualEncoder
         * @memberof communicator_objects.TrainingBehaviorInitialized
         * @instance
         */
        TrainingBehaviorInitialized.prototype.visualEncoder = "";

        /**
         * TrainingBehaviorInitialized numNetworkLayers.
         * @member {number} numNetworkLayers
         * @memberof communicator_objects.TrainingBehaviorInitialized
         * @instance
         */
        TrainingBehaviorInitialized.prototype.numNetworkLayers = 0;

        /**
         * TrainingBehaviorInitialized numNetworkHiddenUnits.
         * @member {number} numNetworkHiddenUnits
         * @memberof communicator_objects.TrainingBehaviorInitialized
         * @instance
         */
        TrainingBehaviorInitialized.prototype.numNetworkHiddenUnits = 0;

        /**
         * TrainingBehaviorInitialized trainerThreaded.
         * @member {boolean} trainerThreaded
         * @memberof communicator_objects.TrainingBehaviorInitialized
         * @instance
         */
        TrainingBehaviorInitialized.prototype.trainerThreaded = false;

        /**
         * TrainingBehaviorInitialized selfPlayEnabled.
         * @member {boolean} selfPlayEnabled
         * @memberof communicator_objects.TrainingBehaviorInitialized
         * @instance
         */
        TrainingBehaviorInitialized.prototype.selfPlayEnabled = false;

        /**
         * TrainingBehaviorInitialized curriculumEnabled.
         * @member {boolean} curriculumEnabled
         * @memberof communicator_objects.TrainingBehaviorInitialized
         * @instance
         */
        TrainingBehaviorInitialized.prototype.curriculumEnabled = false;

        /**
         * TrainingBehaviorInitialized config.
         * @member {string} config
         * @memberof communicator_objects.TrainingBehaviorInitialized
         * @instance
         */
        TrainingBehaviorInitialized.prototype.config = "";

        /**
         * Creates a new TrainingBehaviorInitialized instance using the specified properties.
         * @function create
         * @memberof communicator_objects.TrainingBehaviorInitialized
         * @static
         * @param {communicator_objects.ITrainingBehaviorInitialized=} [properties] Properties to set
         * @returns {communicator_objects.TrainingBehaviorInitialized} TrainingBehaviorInitialized instance
         */
        TrainingBehaviorInitialized.create = function create(properties) {
            return new TrainingBehaviorInitialized(properties);
        };

        /**
         * Encodes the specified TrainingBehaviorInitialized message. Does not implicitly {@link communicator_objects.TrainingBehaviorInitialized.verify|verify} messages.
         * @function encode
         * @memberof communicator_objects.TrainingBehaviorInitialized
         * @static
         * @param {communicator_objects.ITrainingBehaviorInitialized} message TrainingBehaviorInitialized message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        TrainingBehaviorInitialized.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.behaviorName != null && Object.hasOwnProperty.call(message, "behaviorName"))
                writer.uint32(/* id 1, wireType 2 =*/10).string(message.behaviorName);
            if (message.trainerType != null && Object.hasOwnProperty.call(message, "trainerType"))
                writer.uint32(/* id 2, wireType 2 =*/18).string(message.trainerType);
            if (message.extrinsicRewardEnabled != null && Object.hasOwnProperty.call(message, "extrinsicRewardEnabled"))
                writer.uint32(/* id 3, wireType 0 =*/24).bool(message.extrinsicRewardEnabled);
            if (message.gailRewardEnabled != null && Object.hasOwnProperty.call(message, "gailRewardEnabled"))
                writer.uint32(/* id 4, wireType 0 =*/32).bool(message.gailRewardEnabled);
            if (message.curiosityRewardEnabled != null && Object.hasOwnProperty.call(message, "curiosityRewardEnabled"))
                writer.uint32(/* id 5, wireType 0 =*/40).bool(message.curiosityRewardEnabled);
            if (message.rndRewardEnabled != null && Object.hasOwnProperty.call(message, "rndRewardEnabled"))
                writer.uint32(/* id 6, wireType 0 =*/48).bool(message.rndRewardEnabled);
            if (message.behavioralCloningEnabled != null && Object.hasOwnProperty.call(message, "behavioralCloningEnabled"))
                writer.uint32(/* id 7, wireType 0 =*/56).bool(message.behavioralCloningEnabled);
            if (message.recurrentEnabled != null && Object.hasOwnProperty.call(message, "recurrentEnabled"))
                writer.uint32(/* id 8, wireType 0 =*/64).bool(message.recurrentEnabled);
            if (message.visualEncoder != null && Object.hasOwnProperty.call(message, "visualEncoder"))
                writer.uint32(/* id 9, wireType 2 =*/74).string(message.visualEncoder);
            if (message.numNetworkLayers != null && Object.hasOwnProperty.call(message, "numNetworkLayers"))
                writer.uint32(/* id 10, wireType 0 =*/80).int32(message.numNetworkLayers);
            if (message.numNetworkHiddenUnits != null && Object.hasOwnProperty.call(message, "numNetworkHiddenUnits"))
                writer.uint32(/* id 11, wireType 0 =*/88).int32(message.numNetworkHiddenUnits);
            if (message.trainerThreaded != null && Object.hasOwnProperty.call(message, "trainerThreaded"))
                writer.uint32(/* id 12, wireType 0 =*/96).bool(message.trainerThreaded);
            if (message.selfPlayEnabled != null && Object.hasOwnProperty.call(message, "selfPlayEnabled"))
                writer.uint32(/* id 13, wireType 0 =*/104).bool(message.selfPlayEnabled);
            if (message.curriculumEnabled != null && Object.hasOwnProperty.call(message, "curriculumEnabled"))
                writer.uint32(/* id 14, wireType 0 =*/112).bool(message.curriculumEnabled);
            if (message.config != null && Object.hasOwnProperty.call(message, "config"))
                writer.uint32(/* id 15, wireType 2 =*/122).string(message.config);
            return writer;
        };

        /**
         * Encodes the specified TrainingBehaviorInitialized message, length delimited. Does not implicitly {@link communicator_objects.TrainingBehaviorInitialized.verify|verify} messages.
         * @function encodeDelimited
         * @memberof communicator_objects.TrainingBehaviorInitialized
         * @static
         * @param {communicator_objects.ITrainingBehaviorInitialized} message TrainingBehaviorInitialized message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        TrainingBehaviorInitialized.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a TrainingBehaviorInitialized message from the specified reader or buffer.
         * @function decode
         * @memberof communicator_objects.TrainingBehaviorInitialized
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {communicator_objects.TrainingBehaviorInitialized} TrainingBehaviorInitialized
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        TrainingBehaviorInitialized.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.communicator_objects.TrainingBehaviorInitialized();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.behaviorName = reader.string();
                    break;
                case 2:
                    message.trainerType = reader.string();
                    break;
                case 3:
                    message.extrinsicRewardEnabled = reader.bool();
                    break;
                case 4:
                    message.gailRewardEnabled = reader.bool();
                    break;
                case 5:
                    message.curiosityRewardEnabled = reader.bool();
                    break;
                case 6:
                    message.rndRewardEnabled = reader.bool();
                    break;
                case 7:
                    message.behavioralCloningEnabled = reader.bool();
                    break;
                case 8:
                    message.recurrentEnabled = reader.bool();
                    break;
                case 9:
                    message.visualEncoder = reader.string();
                    break;
                case 10:
                    message.numNetworkLayers = reader.int32();
                    break;
                case 11:
                    message.numNetworkHiddenUnits = reader.int32();
                    break;
                case 12:
                    message.trainerThreaded = reader.bool();
                    break;
                case 13:
                    message.selfPlayEnabled = reader.bool();
                    break;
                case 14:
                    message.curriculumEnabled = reader.bool();
                    break;
                case 15:
                    message.config = reader.string();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a TrainingBehaviorInitialized message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof communicator_objects.TrainingBehaviorInitialized
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {communicator_objects.TrainingBehaviorInitialized} TrainingBehaviorInitialized
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        TrainingBehaviorInitialized.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a TrainingBehaviorInitialized message.
         * @function verify
         * @memberof communicator_objects.TrainingBehaviorInitialized
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        TrainingBehaviorInitialized.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.behaviorName != null && message.hasOwnProperty("behaviorName"))
                if (!$util.isString(message.behaviorName))
                    return "behaviorName: string expected";
            if (message.trainerType != null && message.hasOwnProperty("trainerType"))
                if (!$util.isString(message.trainerType))
                    return "trainerType: string expected";
            if (message.extrinsicRewardEnabled != null && message.hasOwnProperty("extrinsicRewardEnabled"))
                if (typeof message.extrinsicRewardEnabled !== "boolean")
                    return "extrinsicRewardEnabled: boolean expected";
            if (message.gailRewardEnabled != null && message.hasOwnProperty("gailRewardEnabled"))
                if (typeof message.gailRewardEnabled !== "boolean")
                    return "gailRewardEnabled: boolean expected";
            if (message.curiosityRewardEnabled != null && message.hasOwnProperty("curiosityRewardEnabled"))
                if (typeof message.curiosityRewardEnabled !== "boolean")
                    return "curiosityRewardEnabled: boolean expected";
            if (message.rndRewardEnabled != null && message.hasOwnProperty("rndRewardEnabled"))
                if (typeof message.rndRewardEnabled !== "boolean")
                    return "rndRewardEnabled: boolean expected";
            if (message.behavioralCloningEnabled != null && message.hasOwnProperty("behavioralCloningEnabled"))
                if (typeof message.behavioralCloningEnabled !== "boolean")
                    return "behavioralCloningEnabled: boolean expected";
            if (message.recurrentEnabled != null && message.hasOwnProperty("recurrentEnabled"))
                if (typeof message.recurrentEnabled !== "boolean")
                    return "recurrentEnabled: boolean expected";
            if (message.visualEncoder != null && message.hasOwnProperty("visualEncoder"))
                if (!$util.isString(message.visualEncoder))
                    return "visualEncoder: string expected";
            if (message.numNetworkLayers != null && message.hasOwnProperty("numNetworkLayers"))
                if (!$util.isInteger(message.numNetworkLayers))
                    return "numNetworkLayers: integer expected";
            if (message.numNetworkHiddenUnits != null && message.hasOwnProperty("numNetworkHiddenUnits"))
                if (!$util.isInteger(message.numNetworkHiddenUnits))
                    return "numNetworkHiddenUnits: integer expected";
            if (message.trainerThreaded != null && message.hasOwnProperty("trainerThreaded"))
                if (typeof message.trainerThreaded !== "boolean")
                    return "trainerThreaded: boolean expected";
            if (message.selfPlayEnabled != null && message.hasOwnProperty("selfPlayEnabled"))
                if (typeof message.selfPlayEnabled !== "boolean")
                    return "selfPlayEnabled: boolean expected";
            if (message.curriculumEnabled != null && message.hasOwnProperty("curriculumEnabled"))
                if (typeof message.curriculumEnabled !== "boolean")
                    return "curriculumEnabled: boolean expected";
            if (message.config != null && message.hasOwnProperty("config"))
                if (!$util.isString(message.config))
                    return "config: string expected";
            return null;
        };

        /**
         * Creates a TrainingBehaviorInitialized message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof communicator_objects.TrainingBehaviorInitialized
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {communicator_objects.TrainingBehaviorInitialized} TrainingBehaviorInitialized
         */
        TrainingBehaviorInitialized.fromObject = function fromObject(object) {
            if (object instanceof $root.communicator_objects.TrainingBehaviorInitialized)
                return object;
            var message = new $root.communicator_objects.TrainingBehaviorInitialized();
            if (object.behaviorName != null)
                message.behaviorName = String(object.behaviorName);
            if (object.trainerType != null)
                message.trainerType = String(object.trainerType);
            if (object.extrinsicRewardEnabled != null)
                message.extrinsicRewardEnabled = Boolean(object.extrinsicRewardEnabled);
            if (object.gailRewardEnabled != null)
                message.gailRewardEnabled = Boolean(object.gailRewardEnabled);
            if (object.curiosityRewardEnabled != null)
                message.curiosityRewardEnabled = Boolean(object.curiosityRewardEnabled);
            if (object.rndRewardEnabled != null)
                message.rndRewardEnabled = Boolean(object.rndRewardEnabled);
            if (object.behavioralCloningEnabled != null)
                message.behavioralCloningEnabled = Boolean(object.behavioralCloningEnabled);
            if (object.recurrentEnabled != null)
                message.recurrentEnabled = Boolean(object.recurrentEnabled);
            if (object.visualEncoder != null)
                message.visualEncoder = String(object.visualEncoder);
            if (object.numNetworkLayers != null)
                message.numNetworkLayers = object.numNetworkLayers | 0;
            if (object.numNetworkHiddenUnits != null)
                message.numNetworkHiddenUnits = object.numNetworkHiddenUnits | 0;
            if (object.trainerThreaded != null)
                message.trainerThreaded = Boolean(object.trainerThreaded);
            if (object.selfPlayEnabled != null)
                message.selfPlayEnabled = Boolean(object.selfPlayEnabled);
            if (object.curriculumEnabled != null)
                message.curriculumEnabled = Boolean(object.curriculumEnabled);
            if (object.config != null)
                message.config = String(object.config);
            return message;
        };

        /**
         * Creates a plain object from a TrainingBehaviorInitialized message. Also converts values to other types if specified.
         * @function toObject
         * @memberof communicator_objects.TrainingBehaviorInitialized
         * @static
         * @param {communicator_objects.TrainingBehaviorInitialized} message TrainingBehaviorInitialized
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        TrainingBehaviorInitialized.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                object.behaviorName = "";
                object.trainerType = "";
                object.extrinsicRewardEnabled = false;
                object.gailRewardEnabled = false;
                object.curiosityRewardEnabled = false;
                object.rndRewardEnabled = false;
                object.behavioralCloningEnabled = false;
                object.recurrentEnabled = false;
                object.visualEncoder = "";
                object.numNetworkLayers = 0;
                object.numNetworkHiddenUnits = 0;
                object.trainerThreaded = false;
                object.selfPlayEnabled = false;
                object.curriculumEnabled = false;
                object.config = "";
            }
            if (message.behaviorName != null && message.hasOwnProperty("behaviorName"))
                object.behaviorName = message.behaviorName;
            if (message.trainerType != null && message.hasOwnProperty("trainerType"))
                object.trainerType = message.trainerType;
            if (message.extrinsicRewardEnabled != null && message.hasOwnProperty("extrinsicRewardEnabled"))
                object.extrinsicRewardEnabled = message.extrinsicRewardEnabled;
            if (message.gailRewardEnabled != null && message.hasOwnProperty("gailRewardEnabled"))
                object.gailRewardEnabled = message.gailRewardEnabled;
            if (message.curiosityRewardEnabled != null && message.hasOwnProperty("curiosityRewardEnabled"))
                object.curiosityRewardEnabled = message.curiosityRewardEnabled;
            if (message.rndRewardEnabled != null && message.hasOwnProperty("rndRewardEnabled"))
                object.rndRewardEnabled = message.rndRewardEnabled;
            if (message.behavioralCloningEnabled != null && message.hasOwnProperty("behavioralCloningEnabled"))
                object.behavioralCloningEnabled = message.behavioralCloningEnabled;
            if (message.recurrentEnabled != null && message.hasOwnProperty("recurrentEnabled"))
                object.recurrentEnabled = message.recurrentEnabled;
            if (message.visualEncoder != null && message.hasOwnProperty("visualEncoder"))
                object.visualEncoder = message.visualEncoder;
            if (message.numNetworkLayers != null && message.hasOwnProperty("numNetworkLayers"))
                object.numNetworkLayers = message.numNetworkLayers;
            if (message.numNetworkHiddenUnits != null && message.hasOwnProperty("numNetworkHiddenUnits"))
                object.numNetworkHiddenUnits = message.numNetworkHiddenUnits;
            if (message.trainerThreaded != null && message.hasOwnProperty("trainerThreaded"))
                object.trainerThreaded = message.trainerThreaded;
            if (message.selfPlayEnabled != null && message.hasOwnProperty("selfPlayEnabled"))
                object.selfPlayEnabled = message.selfPlayEnabled;
            if (message.curriculumEnabled != null && message.hasOwnProperty("curriculumEnabled"))
                object.curriculumEnabled = message.curriculumEnabled;
            if (message.config != null && message.hasOwnProperty("config"))
                object.config = message.config;
            return object;
        };

        /**
         * Converts this TrainingBehaviorInitialized to JSON.
         * @function toJSON
         * @memberof communicator_objects.TrainingBehaviorInitialized
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        TrainingBehaviorInitialized.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return TrainingBehaviorInitialized;
    })();

    communicator_objects.UnityInputProto = (function() {

        /**
         * Properties of an UnityInputProto.
         * @memberof communicator_objects
         * @interface IUnityInputProto
         * @property {communicator_objects.IUnityRLInputProto|null} [rlInput] UnityInputProto rlInput
         * @property {communicator_objects.IUnityRLInitializationInputProto|null} [rlInitializationInput] UnityInputProto rlInitializationInput
         */

        /**
         * Constructs a new UnityInputProto.
         * @memberof communicator_objects
         * @classdesc Represents an UnityInputProto.
         * @implements IUnityInputProto
         * @constructor
         * @param {communicator_objects.IUnityInputProto=} [properties] Properties to set
         */
        function UnityInputProto(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * UnityInputProto rlInput.
         * @member {communicator_objects.IUnityRLInputProto|null|undefined} rlInput
         * @memberof communicator_objects.UnityInputProto
         * @instance
         */
        UnityInputProto.prototype.rlInput = null;

        /**
         * UnityInputProto rlInitializationInput.
         * @member {communicator_objects.IUnityRLInitializationInputProto|null|undefined} rlInitializationInput
         * @memberof communicator_objects.UnityInputProto
         * @instance
         */
        UnityInputProto.prototype.rlInitializationInput = null;

        /**
         * Creates a new UnityInputProto instance using the specified properties.
         * @function create
         * @memberof communicator_objects.UnityInputProto
         * @static
         * @param {communicator_objects.IUnityInputProto=} [properties] Properties to set
         * @returns {communicator_objects.UnityInputProto} UnityInputProto instance
         */
        UnityInputProto.create = function create(properties) {
            return new UnityInputProto(properties);
        };

        /**
         * Encodes the specified UnityInputProto message. Does not implicitly {@link communicator_objects.UnityInputProto.verify|verify} messages.
         * @function encode
         * @memberof communicator_objects.UnityInputProto
         * @static
         * @param {communicator_objects.IUnityInputProto} message UnityInputProto message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        UnityInputProto.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.rlInput != null && Object.hasOwnProperty.call(message, "rlInput"))
                $root.communicator_objects.UnityRLInputProto.encode(message.rlInput, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim();
            if (message.rlInitializationInput != null && Object.hasOwnProperty.call(message, "rlInitializationInput"))
                $root.communicator_objects.UnityRLInitializationInputProto.encode(message.rlInitializationInput, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim();
            return writer;
        };

        /**
         * Encodes the specified UnityInputProto message, length delimited. Does not implicitly {@link communicator_objects.UnityInputProto.verify|verify} messages.
         * @function encodeDelimited
         * @memberof communicator_objects.UnityInputProto
         * @static
         * @param {communicator_objects.IUnityInputProto} message UnityInputProto message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        UnityInputProto.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes an UnityInputProto message from the specified reader or buffer.
         * @function decode
         * @memberof communicator_objects.UnityInputProto
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {communicator_objects.UnityInputProto} UnityInputProto
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        UnityInputProto.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.communicator_objects.UnityInputProto();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.rlInput = $root.communicator_objects.UnityRLInputProto.decode(reader, reader.uint32());
                    break;
                case 2:
                    message.rlInitializationInput = $root.communicator_objects.UnityRLInitializationInputProto.decode(reader, reader.uint32());
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes an UnityInputProto message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof communicator_objects.UnityInputProto
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {communicator_objects.UnityInputProto} UnityInputProto
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        UnityInputProto.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies an UnityInputProto message.
         * @function verify
         * @memberof communicator_objects.UnityInputProto
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        UnityInputProto.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.rlInput != null && message.hasOwnProperty("rlInput")) {
                var error = $root.communicator_objects.UnityRLInputProto.verify(message.rlInput);
                if (error)
                    return "rlInput." + error;
            }
            if (message.rlInitializationInput != null && message.hasOwnProperty("rlInitializationInput")) {
                var error = $root.communicator_objects.UnityRLInitializationInputProto.verify(message.rlInitializationInput);
                if (error)
                    return "rlInitializationInput." + error;
            }
            return null;
        };

        /**
         * Creates an UnityInputProto message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof communicator_objects.UnityInputProto
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {communicator_objects.UnityInputProto} UnityInputProto
         */
        UnityInputProto.fromObject = function fromObject(object) {
            if (object instanceof $root.communicator_objects.UnityInputProto)
                return object;
            var message = new $root.communicator_objects.UnityInputProto();
            if (object.rlInput != null) {
                if (typeof object.rlInput !== "object")
                    throw TypeError(".communicator_objects.UnityInputProto.rlInput: object expected");
                message.rlInput = $root.communicator_objects.UnityRLInputProto.fromObject(object.rlInput);
            }
            if (object.rlInitializationInput != null) {
                if (typeof object.rlInitializationInput !== "object")
                    throw TypeError(".communicator_objects.UnityInputProto.rlInitializationInput: object expected");
                message.rlInitializationInput = $root.communicator_objects.UnityRLInitializationInputProto.fromObject(object.rlInitializationInput);
            }
            return message;
        };

        /**
         * Creates a plain object from an UnityInputProto message. Also converts values to other types if specified.
         * @function toObject
         * @memberof communicator_objects.UnityInputProto
         * @static
         * @param {communicator_objects.UnityInputProto} message UnityInputProto
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        UnityInputProto.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                object.rlInput = null;
                object.rlInitializationInput = null;
            }
            if (message.rlInput != null && message.hasOwnProperty("rlInput"))
                object.rlInput = $root.communicator_objects.UnityRLInputProto.toObject(message.rlInput, options);
            if (message.rlInitializationInput != null && message.hasOwnProperty("rlInitializationInput"))
                object.rlInitializationInput = $root.communicator_objects.UnityRLInitializationInputProto.toObject(message.rlInitializationInput, options);
            return object;
        };

        /**
         * Converts this UnityInputProto to JSON.
         * @function toJSON
         * @memberof communicator_objects.UnityInputProto
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        UnityInputProto.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return UnityInputProto;
    })();

    communicator_objects.UnityMessageProto = (function() {

        /**
         * Properties of an UnityMessageProto.
         * @memberof communicator_objects
         * @interface IUnityMessageProto
         * @property {communicator_objects.IHeaderProto|null} [header] UnityMessageProto header
         * @property {communicator_objects.IUnityOutputProto|null} [unityOutput] UnityMessageProto unityOutput
         * @property {communicator_objects.IUnityInputProto|null} [unityInput] UnityMessageProto unityInput
         */

        /**
         * Constructs a new UnityMessageProto.
         * @memberof communicator_objects
         * @classdesc Represents an UnityMessageProto.
         * @implements IUnityMessageProto
         * @constructor
         * @param {communicator_objects.IUnityMessageProto=} [properties] Properties to set
         */
        function UnityMessageProto(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * UnityMessageProto header.
         * @member {communicator_objects.IHeaderProto|null|undefined} header
         * @memberof communicator_objects.UnityMessageProto
         * @instance
         */
        UnityMessageProto.prototype.header = null;

        /**
         * UnityMessageProto unityOutput.
         * @member {communicator_objects.IUnityOutputProto|null|undefined} unityOutput
         * @memberof communicator_objects.UnityMessageProto
         * @instance
         */
        UnityMessageProto.prototype.unityOutput = null;

        /**
         * UnityMessageProto unityInput.
         * @member {communicator_objects.IUnityInputProto|null|undefined} unityInput
         * @memberof communicator_objects.UnityMessageProto
         * @instance
         */
        UnityMessageProto.prototype.unityInput = null;

        /**
         * Creates a new UnityMessageProto instance using the specified properties.
         * @function create
         * @memberof communicator_objects.UnityMessageProto
         * @static
         * @param {communicator_objects.IUnityMessageProto=} [properties] Properties to set
         * @returns {communicator_objects.UnityMessageProto} UnityMessageProto instance
         */
        UnityMessageProto.create = function create(properties) {
            return new UnityMessageProto(properties);
        };

        /**
         * Encodes the specified UnityMessageProto message. Does not implicitly {@link communicator_objects.UnityMessageProto.verify|verify} messages.
         * @function encode
         * @memberof communicator_objects.UnityMessageProto
         * @static
         * @param {communicator_objects.IUnityMessageProto} message UnityMessageProto message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        UnityMessageProto.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.header != null && Object.hasOwnProperty.call(message, "header"))
                $root.communicator_objects.HeaderProto.encode(message.header, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim();
            if (message.unityOutput != null && Object.hasOwnProperty.call(message, "unityOutput"))
                $root.communicator_objects.UnityOutputProto.encode(message.unityOutput, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim();
            if (message.unityInput != null && Object.hasOwnProperty.call(message, "unityInput"))
                $root.communicator_objects.UnityInputProto.encode(message.unityInput, writer.uint32(/* id 3, wireType 2 =*/26).fork()).ldelim();
            return writer;
        };

        /**
         * Encodes the specified UnityMessageProto message, length delimited. Does not implicitly {@link communicator_objects.UnityMessageProto.verify|verify} messages.
         * @function encodeDelimited
         * @memberof communicator_objects.UnityMessageProto
         * @static
         * @param {communicator_objects.IUnityMessageProto} message UnityMessageProto message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        UnityMessageProto.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes an UnityMessageProto message from the specified reader or buffer.
         * @function decode
         * @memberof communicator_objects.UnityMessageProto
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {communicator_objects.UnityMessageProto} UnityMessageProto
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        UnityMessageProto.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.communicator_objects.UnityMessageProto();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.header = $root.communicator_objects.HeaderProto.decode(reader, reader.uint32());
                    break;
                case 2:
                    message.unityOutput = $root.communicator_objects.UnityOutputProto.decode(reader, reader.uint32());
                    break;
                case 3:
                    message.unityInput = $root.communicator_objects.UnityInputProto.decode(reader, reader.uint32());
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes an UnityMessageProto message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof communicator_objects.UnityMessageProto
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {communicator_objects.UnityMessageProto} UnityMessageProto
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        UnityMessageProto.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies an UnityMessageProto message.
         * @function verify
         * @memberof communicator_objects.UnityMessageProto
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        UnityMessageProto.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.header != null && message.hasOwnProperty("header")) {
                var error = $root.communicator_objects.HeaderProto.verify(message.header);
                if (error)
                    return "header." + error;
            }
            if (message.unityOutput != null && message.hasOwnProperty("unityOutput")) {
                var error = $root.communicator_objects.UnityOutputProto.verify(message.unityOutput);
                if (error)
                    return "unityOutput." + error;
            }
            if (message.unityInput != null && message.hasOwnProperty("unityInput")) {
                var error = $root.communicator_objects.UnityInputProto.verify(message.unityInput);
                if (error)
                    return "unityInput." + error;
            }
            return null;
        };

        /**
         * Creates an UnityMessageProto message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof communicator_objects.UnityMessageProto
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {communicator_objects.UnityMessageProto} UnityMessageProto
         */
        UnityMessageProto.fromObject = function fromObject(object) {
            if (object instanceof $root.communicator_objects.UnityMessageProto)
                return object;
            var message = new $root.communicator_objects.UnityMessageProto();
            if (object.header != null) {
                if (typeof object.header !== "object")
                    throw TypeError(".communicator_objects.UnityMessageProto.header: object expected");
                message.header = $root.communicator_objects.HeaderProto.fromObject(object.header);
            }
            if (object.unityOutput != null) {
                if (typeof object.unityOutput !== "object")
                    throw TypeError(".communicator_objects.UnityMessageProto.unityOutput: object expected");
                message.unityOutput = $root.communicator_objects.UnityOutputProto.fromObject(object.unityOutput);
            }
            if (object.unityInput != null) {
                if (typeof object.unityInput !== "object")
                    throw TypeError(".communicator_objects.UnityMessageProto.unityInput: object expected");
                message.unityInput = $root.communicator_objects.UnityInputProto.fromObject(object.unityInput);
            }
            return message;
        };

        /**
         * Creates a plain object from an UnityMessageProto message. Also converts values to other types if specified.
         * @function toObject
         * @memberof communicator_objects.UnityMessageProto
         * @static
         * @param {communicator_objects.UnityMessageProto} message UnityMessageProto
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        UnityMessageProto.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                object.header = null;
                object.unityOutput = null;
                object.unityInput = null;
            }
            if (message.header != null && message.hasOwnProperty("header"))
                object.header = $root.communicator_objects.HeaderProto.toObject(message.header, options);
            if (message.unityOutput != null && message.hasOwnProperty("unityOutput"))
                object.unityOutput = $root.communicator_objects.UnityOutputProto.toObject(message.unityOutput, options);
            if (message.unityInput != null && message.hasOwnProperty("unityInput"))
                object.unityInput = $root.communicator_objects.UnityInputProto.toObject(message.unityInput, options);
            return object;
        };

        /**
         * Converts this UnityMessageProto to JSON.
         * @function toJSON
         * @memberof communicator_objects.UnityMessageProto
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        UnityMessageProto.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return UnityMessageProto;
    })();

    communicator_objects.UnityOutputProto = (function() {

        /**
         * Properties of an UnityOutputProto.
         * @memberof communicator_objects
         * @interface IUnityOutputProto
         * @property {communicator_objects.IUnityRLOutputProto|null} [rlOutput] UnityOutputProto rlOutput
         * @property {communicator_objects.IUnityRLInitializationOutputProto|null} [rlInitializationOutput] UnityOutputProto rlInitializationOutput
         */

        /**
         * Constructs a new UnityOutputProto.
         * @memberof communicator_objects
         * @classdesc Represents an UnityOutputProto.
         * @implements IUnityOutputProto
         * @constructor
         * @param {communicator_objects.IUnityOutputProto=} [properties] Properties to set
         */
        function UnityOutputProto(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * UnityOutputProto rlOutput.
         * @member {communicator_objects.IUnityRLOutputProto|null|undefined} rlOutput
         * @memberof communicator_objects.UnityOutputProto
         * @instance
         */
        UnityOutputProto.prototype.rlOutput = null;

        /**
         * UnityOutputProto rlInitializationOutput.
         * @member {communicator_objects.IUnityRLInitializationOutputProto|null|undefined} rlInitializationOutput
         * @memberof communicator_objects.UnityOutputProto
         * @instance
         */
        UnityOutputProto.prototype.rlInitializationOutput = null;

        /**
         * Creates a new UnityOutputProto instance using the specified properties.
         * @function create
         * @memberof communicator_objects.UnityOutputProto
         * @static
         * @param {communicator_objects.IUnityOutputProto=} [properties] Properties to set
         * @returns {communicator_objects.UnityOutputProto} UnityOutputProto instance
         */
        UnityOutputProto.create = function create(properties) {
            return new UnityOutputProto(properties);
        };

        /**
         * Encodes the specified UnityOutputProto message. Does not implicitly {@link communicator_objects.UnityOutputProto.verify|verify} messages.
         * @function encode
         * @memberof communicator_objects.UnityOutputProto
         * @static
         * @param {communicator_objects.IUnityOutputProto} message UnityOutputProto message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        UnityOutputProto.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.rlOutput != null && Object.hasOwnProperty.call(message, "rlOutput"))
                $root.communicator_objects.UnityRLOutputProto.encode(message.rlOutput, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim();
            if (message.rlInitializationOutput != null && Object.hasOwnProperty.call(message, "rlInitializationOutput"))
                $root.communicator_objects.UnityRLInitializationOutputProto.encode(message.rlInitializationOutput, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim();
            return writer;
        };

        /**
         * Encodes the specified UnityOutputProto message, length delimited. Does not implicitly {@link communicator_objects.UnityOutputProto.verify|verify} messages.
         * @function encodeDelimited
         * @memberof communicator_objects.UnityOutputProto
         * @static
         * @param {communicator_objects.IUnityOutputProto} message UnityOutputProto message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        UnityOutputProto.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes an UnityOutputProto message from the specified reader or buffer.
         * @function decode
         * @memberof communicator_objects.UnityOutputProto
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {communicator_objects.UnityOutputProto} UnityOutputProto
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        UnityOutputProto.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.communicator_objects.UnityOutputProto();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.rlOutput = $root.communicator_objects.UnityRLOutputProto.decode(reader, reader.uint32());
                    break;
                case 2:
                    message.rlInitializationOutput = $root.communicator_objects.UnityRLInitializationOutputProto.decode(reader, reader.uint32());
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes an UnityOutputProto message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof communicator_objects.UnityOutputProto
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {communicator_objects.UnityOutputProto} UnityOutputProto
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        UnityOutputProto.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies an UnityOutputProto message.
         * @function verify
         * @memberof communicator_objects.UnityOutputProto
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        UnityOutputProto.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.rlOutput != null && message.hasOwnProperty("rlOutput")) {
                var error = $root.communicator_objects.UnityRLOutputProto.verify(message.rlOutput);
                if (error)
                    return "rlOutput." + error;
            }
            if (message.rlInitializationOutput != null && message.hasOwnProperty("rlInitializationOutput")) {
                var error = $root.communicator_objects.UnityRLInitializationOutputProto.verify(message.rlInitializationOutput);
                if (error)
                    return "rlInitializationOutput." + error;
            }
            return null;
        };

        /**
         * Creates an UnityOutputProto message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof communicator_objects.UnityOutputProto
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {communicator_objects.UnityOutputProto} UnityOutputProto
         */
        UnityOutputProto.fromObject = function fromObject(object) {
            if (object instanceof $root.communicator_objects.UnityOutputProto)
                return object;
            var message = new $root.communicator_objects.UnityOutputProto();
            if (object.rlOutput != null) {
                if (typeof object.rlOutput !== "object")
                    throw TypeError(".communicator_objects.UnityOutputProto.rlOutput: object expected");
                message.rlOutput = $root.communicator_objects.UnityRLOutputProto.fromObject(object.rlOutput);
            }
            if (object.rlInitializationOutput != null) {
                if (typeof object.rlInitializationOutput !== "object")
                    throw TypeError(".communicator_objects.UnityOutputProto.rlInitializationOutput: object expected");
                message.rlInitializationOutput = $root.communicator_objects.UnityRLInitializationOutputProto.fromObject(object.rlInitializationOutput);
            }
            return message;
        };

        /**
         * Creates a plain object from an UnityOutputProto message. Also converts values to other types if specified.
         * @function toObject
         * @memberof communicator_objects.UnityOutputProto
         * @static
         * @param {communicator_objects.UnityOutputProto} message UnityOutputProto
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        UnityOutputProto.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                object.rlOutput = null;
                object.rlInitializationOutput = null;
            }
            if (message.rlOutput != null && message.hasOwnProperty("rlOutput"))
                object.rlOutput = $root.communicator_objects.UnityRLOutputProto.toObject(message.rlOutput, options);
            if (message.rlInitializationOutput != null && message.hasOwnProperty("rlInitializationOutput"))
                object.rlInitializationOutput = $root.communicator_objects.UnityRLInitializationOutputProto.toObject(message.rlInitializationOutput, options);
            return object;
        };

        /**
         * Converts this UnityOutputProto to JSON.
         * @function toJSON
         * @memberof communicator_objects.UnityOutputProto
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        UnityOutputProto.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return UnityOutputProto;
    })();

    communicator_objects.UnityRLInitializationInputProto = (function() {

        /**
         * Properties of an UnityRLInitializationInputProto.
         * @memberof communicator_objects
         * @interface IUnityRLInitializationInputProto
         * @property {number|null} [seed] UnityRLInitializationInputProto seed
         * @property {string|null} [communicationVersion] UnityRLInitializationInputProto communicationVersion
         * @property {string|null} [packageVersion] UnityRLInitializationInputProto packageVersion
         * @property {communicator_objects.IUnityRLCapabilitiesProto|null} [capabilities] UnityRLInitializationInputProto capabilities
         * @property {number|null} [numAreas] UnityRLInitializationInputProto numAreas
         */

        /**
         * Constructs a new UnityRLInitializationInputProto.
         * @memberof communicator_objects
         * @classdesc Represents an UnityRLInitializationInputProto.
         * @implements IUnityRLInitializationInputProto
         * @constructor
         * @param {communicator_objects.IUnityRLInitializationInputProto=} [properties] Properties to set
         */
        function UnityRLInitializationInputProto(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * UnityRLInitializationInputProto seed.
         * @member {number} seed
         * @memberof communicator_objects.UnityRLInitializationInputProto
         * @instance
         */
        UnityRLInitializationInputProto.prototype.seed = 0;

        /**
         * UnityRLInitializationInputProto communicationVersion.
         * @member {string} communicationVersion
         * @memberof communicator_objects.UnityRLInitializationInputProto
         * @instance
         */
        UnityRLInitializationInputProto.prototype.communicationVersion = "";

        /**
         * UnityRLInitializationInputProto packageVersion.
         * @member {string} packageVersion
         * @memberof communicator_objects.UnityRLInitializationInputProto
         * @instance
         */
        UnityRLInitializationInputProto.prototype.packageVersion = "";

        /**
         * UnityRLInitializationInputProto capabilities.
         * @member {communicator_objects.IUnityRLCapabilitiesProto|null|undefined} capabilities
         * @memberof communicator_objects.UnityRLInitializationInputProto
         * @instance
         */
        UnityRLInitializationInputProto.prototype.capabilities = null;

        /**
         * UnityRLInitializationInputProto numAreas.
         * @member {number} numAreas
         * @memberof communicator_objects.UnityRLInitializationInputProto
         * @instance
         */
        UnityRLInitializationInputProto.prototype.numAreas = 0;

        /**
         * Creates a new UnityRLInitializationInputProto instance using the specified properties.
         * @function create
         * @memberof communicator_objects.UnityRLInitializationInputProto
         * @static
         * @param {communicator_objects.IUnityRLInitializationInputProto=} [properties] Properties to set
         * @returns {communicator_objects.UnityRLInitializationInputProto} UnityRLInitializationInputProto instance
         */
        UnityRLInitializationInputProto.create = function create(properties) {
            return new UnityRLInitializationInputProto(properties);
        };

        /**
         * Encodes the specified UnityRLInitializationInputProto message. Does not implicitly {@link communicator_objects.UnityRLInitializationInputProto.verify|verify} messages.
         * @function encode
         * @memberof communicator_objects.UnityRLInitializationInputProto
         * @static
         * @param {communicator_objects.IUnityRLInitializationInputProto} message UnityRLInitializationInputProto message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        UnityRLInitializationInputProto.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.seed != null && Object.hasOwnProperty.call(message, "seed"))
                writer.uint32(/* id 1, wireType 0 =*/8).int32(message.seed);
            if (message.communicationVersion != null && Object.hasOwnProperty.call(message, "communicationVersion"))
                writer.uint32(/* id 2, wireType 2 =*/18).string(message.communicationVersion);
            if (message.packageVersion != null && Object.hasOwnProperty.call(message, "packageVersion"))
                writer.uint32(/* id 3, wireType 2 =*/26).string(message.packageVersion);
            if (message.capabilities != null && Object.hasOwnProperty.call(message, "capabilities"))
                $root.communicator_objects.UnityRLCapabilitiesProto.encode(message.capabilities, writer.uint32(/* id 4, wireType 2 =*/34).fork()).ldelim();
            if (message.numAreas != null && Object.hasOwnProperty.call(message, "numAreas"))
                writer.uint32(/* id 5, wireType 0 =*/40).int32(message.numAreas);
            return writer;
        };

        /**
         * Encodes the specified UnityRLInitializationInputProto message, length delimited. Does not implicitly {@link communicator_objects.UnityRLInitializationInputProto.verify|verify} messages.
         * @function encodeDelimited
         * @memberof communicator_objects.UnityRLInitializationInputProto
         * @static
         * @param {communicator_objects.IUnityRLInitializationInputProto} message UnityRLInitializationInputProto message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        UnityRLInitializationInputProto.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes an UnityRLInitializationInputProto message from the specified reader or buffer.
         * @function decode
         * @memberof communicator_objects.UnityRLInitializationInputProto
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {communicator_objects.UnityRLInitializationInputProto} UnityRLInitializationInputProto
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        UnityRLInitializationInputProto.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.communicator_objects.UnityRLInitializationInputProto();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.seed = reader.int32();
                    break;
                case 2:
                    message.communicationVersion = reader.string();
                    break;
                case 3:
                    message.packageVersion = reader.string();
                    break;
                case 4:
                    message.capabilities = $root.communicator_objects.UnityRLCapabilitiesProto.decode(reader, reader.uint32());
                    break;
                case 5:
                    message.numAreas = reader.int32();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes an UnityRLInitializationInputProto message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof communicator_objects.UnityRLInitializationInputProto
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {communicator_objects.UnityRLInitializationInputProto} UnityRLInitializationInputProto
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        UnityRLInitializationInputProto.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies an UnityRLInitializationInputProto message.
         * @function verify
         * @memberof communicator_objects.UnityRLInitializationInputProto
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        UnityRLInitializationInputProto.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.seed != null && message.hasOwnProperty("seed"))
                if (!$util.isInteger(message.seed))
                    return "seed: integer expected";
            if (message.communicationVersion != null && message.hasOwnProperty("communicationVersion"))
                if (!$util.isString(message.communicationVersion))
                    return "communicationVersion: string expected";
            if (message.packageVersion != null && message.hasOwnProperty("packageVersion"))
                if (!$util.isString(message.packageVersion))
                    return "packageVersion: string expected";
            if (message.capabilities != null && message.hasOwnProperty("capabilities")) {
                var error = $root.communicator_objects.UnityRLCapabilitiesProto.verify(message.capabilities);
                if (error)
                    return "capabilities." + error;
            }
            if (message.numAreas != null && message.hasOwnProperty("numAreas"))
                if (!$util.isInteger(message.numAreas))
                    return "numAreas: integer expected";
            return null;
        };

        /**
         * Creates an UnityRLInitializationInputProto message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof communicator_objects.UnityRLInitializationInputProto
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {communicator_objects.UnityRLInitializationInputProto} UnityRLInitializationInputProto
         */
        UnityRLInitializationInputProto.fromObject = function fromObject(object) {
            if (object instanceof $root.communicator_objects.UnityRLInitializationInputProto)
                return object;
            var message = new $root.communicator_objects.UnityRLInitializationInputProto();
            if (object.seed != null)
                message.seed = object.seed | 0;
            if (object.communicationVersion != null)
                message.communicationVersion = String(object.communicationVersion);
            if (object.packageVersion != null)
                message.packageVersion = String(object.packageVersion);
            if (object.capabilities != null) {
                if (typeof object.capabilities !== "object")
                    throw TypeError(".communicator_objects.UnityRLInitializationInputProto.capabilities: object expected");
                message.capabilities = $root.communicator_objects.UnityRLCapabilitiesProto.fromObject(object.capabilities);
            }
            if (object.numAreas != null)
                message.numAreas = object.numAreas | 0;
            return message;
        };

        /**
         * Creates a plain object from an UnityRLInitializationInputProto message. Also converts values to other types if specified.
         * @function toObject
         * @memberof communicator_objects.UnityRLInitializationInputProto
         * @static
         * @param {communicator_objects.UnityRLInitializationInputProto} message UnityRLInitializationInputProto
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        UnityRLInitializationInputProto.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                object.seed = 0;
                object.communicationVersion = "";
                object.packageVersion = "";
                object.capabilities = null;
                object.numAreas = 0;
            }
            if (message.seed != null && message.hasOwnProperty("seed"))
                object.seed = message.seed;
            if (message.communicationVersion != null && message.hasOwnProperty("communicationVersion"))
                object.communicationVersion = message.communicationVersion;
            if (message.packageVersion != null && message.hasOwnProperty("packageVersion"))
                object.packageVersion = message.packageVersion;
            if (message.capabilities != null && message.hasOwnProperty("capabilities"))
                object.capabilities = $root.communicator_objects.UnityRLCapabilitiesProto.toObject(message.capabilities, options);
            if (message.numAreas != null && message.hasOwnProperty("numAreas"))
                object.numAreas = message.numAreas;
            return object;
        };

        /**
         * Converts this UnityRLInitializationInputProto to JSON.
         * @function toJSON
         * @memberof communicator_objects.UnityRLInitializationInputProto
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        UnityRLInitializationInputProto.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return UnityRLInitializationInputProto;
    })();

    communicator_objects.UnityRLInitializationOutputProto = (function() {

        /**
         * Properties of an UnityRLInitializationOutputProto.
         * @memberof communicator_objects
         * @interface IUnityRLInitializationOutputProto
         * @property {string|null} [name] UnityRLInitializationOutputProto name
         * @property {string|null} [communicationVersion] UnityRLInitializationOutputProto communicationVersion
         * @property {string|null} [logPath] UnityRLInitializationOutputProto logPath
         * @property {Array.<communicator_objects.IBrainParametersProto>|null} [brainParameters] UnityRLInitializationOutputProto brainParameters
         * @property {string|null} [packageVersion] UnityRLInitializationOutputProto packageVersion
         * @property {communicator_objects.IUnityRLCapabilitiesProto|null} [capabilities] UnityRLInitializationOutputProto capabilities
         */

        /**
         * Constructs a new UnityRLInitializationOutputProto.
         * @memberof communicator_objects
         * @classdesc Represents an UnityRLInitializationOutputProto.
         * @implements IUnityRLInitializationOutputProto
         * @constructor
         * @param {communicator_objects.IUnityRLInitializationOutputProto=} [properties] Properties to set
         */
        function UnityRLInitializationOutputProto(properties) {
            this.brainParameters = [];
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * UnityRLInitializationOutputProto name.
         * @member {string} name
         * @memberof communicator_objects.UnityRLInitializationOutputProto
         * @instance
         */
        UnityRLInitializationOutputProto.prototype.name = "";

        /**
         * UnityRLInitializationOutputProto communicationVersion.
         * @member {string} communicationVersion
         * @memberof communicator_objects.UnityRLInitializationOutputProto
         * @instance
         */
        UnityRLInitializationOutputProto.prototype.communicationVersion = "";

        /**
         * UnityRLInitializationOutputProto logPath.
         * @member {string} logPath
         * @memberof communicator_objects.UnityRLInitializationOutputProto
         * @instance
         */
        UnityRLInitializationOutputProto.prototype.logPath = "";

        /**
         * UnityRLInitializationOutputProto brainParameters.
         * @member {Array.<communicator_objects.IBrainParametersProto>} brainParameters
         * @memberof communicator_objects.UnityRLInitializationOutputProto
         * @instance
         */
        UnityRLInitializationOutputProto.prototype.brainParameters = $util.emptyArray;

        /**
         * UnityRLInitializationOutputProto packageVersion.
         * @member {string} packageVersion
         * @memberof communicator_objects.UnityRLInitializationOutputProto
         * @instance
         */
        UnityRLInitializationOutputProto.prototype.packageVersion = "";

        /**
         * UnityRLInitializationOutputProto capabilities.
         * @member {communicator_objects.IUnityRLCapabilitiesProto|null|undefined} capabilities
         * @memberof communicator_objects.UnityRLInitializationOutputProto
         * @instance
         */
        UnityRLInitializationOutputProto.prototype.capabilities = null;

        /**
         * Creates a new UnityRLInitializationOutputProto instance using the specified properties.
         * @function create
         * @memberof communicator_objects.UnityRLInitializationOutputProto
         * @static
         * @param {communicator_objects.IUnityRLInitializationOutputProto=} [properties] Properties to set
         * @returns {communicator_objects.UnityRLInitializationOutputProto} UnityRLInitializationOutputProto instance
         */
        UnityRLInitializationOutputProto.create = function create(properties) {
            return new UnityRLInitializationOutputProto(properties);
        };

        /**
         * Encodes the specified UnityRLInitializationOutputProto message. Does not implicitly {@link communicator_objects.UnityRLInitializationOutputProto.verify|verify} messages.
         * @function encode
         * @memberof communicator_objects.UnityRLInitializationOutputProto
         * @static
         * @param {communicator_objects.IUnityRLInitializationOutputProto} message UnityRLInitializationOutputProto message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        UnityRLInitializationOutputProto.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.name != null && Object.hasOwnProperty.call(message, "name"))
                writer.uint32(/* id 1, wireType 2 =*/10).string(message.name);
            if (message.communicationVersion != null && Object.hasOwnProperty.call(message, "communicationVersion"))
                writer.uint32(/* id 2, wireType 2 =*/18).string(message.communicationVersion);
            if (message.logPath != null && Object.hasOwnProperty.call(message, "logPath"))
                writer.uint32(/* id 3, wireType 2 =*/26).string(message.logPath);
            if (message.brainParameters != null && message.brainParameters.length)
                for (var i = 0; i < message.brainParameters.length; ++i)
                    $root.communicator_objects.BrainParametersProto.encode(message.brainParameters[i], writer.uint32(/* id 5, wireType 2 =*/42).fork()).ldelim();
            if (message.packageVersion != null && Object.hasOwnProperty.call(message, "packageVersion"))
                writer.uint32(/* id 7, wireType 2 =*/58).string(message.packageVersion);
            if (message.capabilities != null && Object.hasOwnProperty.call(message, "capabilities"))
                $root.communicator_objects.UnityRLCapabilitiesProto.encode(message.capabilities, writer.uint32(/* id 8, wireType 2 =*/66).fork()).ldelim();
            return writer;
        };

        /**
         * Encodes the specified UnityRLInitializationOutputProto message, length delimited. Does not implicitly {@link communicator_objects.UnityRLInitializationOutputProto.verify|verify} messages.
         * @function encodeDelimited
         * @memberof communicator_objects.UnityRLInitializationOutputProto
         * @static
         * @param {communicator_objects.IUnityRLInitializationOutputProto} message UnityRLInitializationOutputProto message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        UnityRLInitializationOutputProto.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes an UnityRLInitializationOutputProto message from the specified reader or buffer.
         * @function decode
         * @memberof communicator_objects.UnityRLInitializationOutputProto
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {communicator_objects.UnityRLInitializationOutputProto} UnityRLInitializationOutputProto
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        UnityRLInitializationOutputProto.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.communicator_objects.UnityRLInitializationOutputProto();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.name = reader.string();
                    break;
                case 2:
                    message.communicationVersion = reader.string();
                    break;
                case 3:
                    message.logPath = reader.string();
                    break;
                case 5:
                    if (!(message.brainParameters && message.brainParameters.length))
                        message.brainParameters = [];
                    message.brainParameters.push($root.communicator_objects.BrainParametersProto.decode(reader, reader.uint32()));
                    break;
                case 7:
                    message.packageVersion = reader.string();
                    break;
                case 8:
                    message.capabilities = $root.communicator_objects.UnityRLCapabilitiesProto.decode(reader, reader.uint32());
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes an UnityRLInitializationOutputProto message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof communicator_objects.UnityRLInitializationOutputProto
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {communicator_objects.UnityRLInitializationOutputProto} UnityRLInitializationOutputProto
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        UnityRLInitializationOutputProto.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies an UnityRLInitializationOutputProto message.
         * @function verify
         * @memberof communicator_objects.UnityRLInitializationOutputProto
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        UnityRLInitializationOutputProto.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.name != null && message.hasOwnProperty("name"))
                if (!$util.isString(message.name))
                    return "name: string expected";
            if (message.communicationVersion != null && message.hasOwnProperty("communicationVersion"))
                if (!$util.isString(message.communicationVersion))
                    return "communicationVersion: string expected";
            if (message.logPath != null && message.hasOwnProperty("logPath"))
                if (!$util.isString(message.logPath))
                    return "logPath: string expected";
            if (message.brainParameters != null && message.hasOwnProperty("brainParameters")) {
                if (!Array.isArray(message.brainParameters))
                    return "brainParameters: array expected";
                for (var i = 0; i < message.brainParameters.length; ++i) {
                    var error = $root.communicator_objects.BrainParametersProto.verify(message.brainParameters[i]);
                    if (error)
                        return "brainParameters." + error;
                }
            }
            if (message.packageVersion != null && message.hasOwnProperty("packageVersion"))
                if (!$util.isString(message.packageVersion))
                    return "packageVersion: string expected";
            if (message.capabilities != null && message.hasOwnProperty("capabilities")) {
                var error = $root.communicator_objects.UnityRLCapabilitiesProto.verify(message.capabilities);
                if (error)
                    return "capabilities." + error;
            }
            return null;
        };

        /**
         * Creates an UnityRLInitializationOutputProto message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof communicator_objects.UnityRLInitializationOutputProto
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {communicator_objects.UnityRLInitializationOutputProto} UnityRLInitializationOutputProto
         */
        UnityRLInitializationOutputProto.fromObject = function fromObject(object) {
            if (object instanceof $root.communicator_objects.UnityRLInitializationOutputProto)
                return object;
            var message = new $root.communicator_objects.UnityRLInitializationOutputProto();
            if (object.name != null)
                message.name = String(object.name);
            if (object.communicationVersion != null)
                message.communicationVersion = String(object.communicationVersion);
            if (object.logPath != null)
                message.logPath = String(object.logPath);
            if (object.brainParameters) {
                if (!Array.isArray(object.brainParameters))
                    throw TypeError(".communicator_objects.UnityRLInitializationOutputProto.brainParameters: array expected");
                message.brainParameters = [];
                for (var i = 0; i < object.brainParameters.length; ++i) {
                    if (typeof object.brainParameters[i] !== "object")
                        throw TypeError(".communicator_objects.UnityRLInitializationOutputProto.brainParameters: object expected");
                    message.brainParameters[i] = $root.communicator_objects.BrainParametersProto.fromObject(object.brainParameters[i]);
                }
            }
            if (object.packageVersion != null)
                message.packageVersion = String(object.packageVersion);
            if (object.capabilities != null) {
                if (typeof object.capabilities !== "object")
                    throw TypeError(".communicator_objects.UnityRLInitializationOutputProto.capabilities: object expected");
                message.capabilities = $root.communicator_objects.UnityRLCapabilitiesProto.fromObject(object.capabilities);
            }
            return message;
        };

        /**
         * Creates a plain object from an UnityRLInitializationOutputProto message. Also converts values to other types if specified.
         * @function toObject
         * @memberof communicator_objects.UnityRLInitializationOutputProto
         * @static
         * @param {communicator_objects.UnityRLInitializationOutputProto} message UnityRLInitializationOutputProto
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        UnityRLInitializationOutputProto.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.arrays || options.defaults)
                object.brainParameters = [];
            if (options.defaults) {
                object.name = "";
                object.communicationVersion = "";
                object.logPath = "";
                object.packageVersion = "";
                object.capabilities = null;
            }
            if (message.name != null && message.hasOwnProperty("name"))
                object.name = message.name;
            if (message.communicationVersion != null && message.hasOwnProperty("communicationVersion"))
                object.communicationVersion = message.communicationVersion;
            if (message.logPath != null && message.hasOwnProperty("logPath"))
                object.logPath = message.logPath;
            if (message.brainParameters && message.brainParameters.length) {
                object.brainParameters = [];
                for (var j = 0; j < message.brainParameters.length; ++j)
                    object.brainParameters[j] = $root.communicator_objects.BrainParametersProto.toObject(message.brainParameters[j], options);
            }
            if (message.packageVersion != null && message.hasOwnProperty("packageVersion"))
                object.packageVersion = message.packageVersion;
            if (message.capabilities != null && message.hasOwnProperty("capabilities"))
                object.capabilities = $root.communicator_objects.UnityRLCapabilitiesProto.toObject(message.capabilities, options);
            return object;
        };

        /**
         * Converts this UnityRLInitializationOutputProto to JSON.
         * @function toJSON
         * @memberof communicator_objects.UnityRLInitializationOutputProto
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        UnityRLInitializationOutputProto.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return UnityRLInitializationOutputProto;
    })();

    communicator_objects.UnityRLInputProto = (function() {

        /**
         * Properties of an UnityRLInputProto.
         * @memberof communicator_objects
         * @interface IUnityRLInputProto
         * @property {Object.<string,communicator_objects.UnityRLInputProto.IListAgentActionProto>|null} [agentActions] UnityRLInputProto agentActions
         * @property {communicator_objects.CommandProto|null} [command] UnityRLInputProto command
         * @property {Uint8Array|null} [sideChannel] UnityRLInputProto sideChannel
         */

        /**
         * Constructs a new UnityRLInputProto.
         * @memberof communicator_objects
         * @classdesc Represents an UnityRLInputProto.
         * @implements IUnityRLInputProto
         * @constructor
         * @param {communicator_objects.IUnityRLInputProto=} [properties] Properties to set
         */
        function UnityRLInputProto(properties) {
            this.agentActions = {};
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * UnityRLInputProto agentActions.
         * @member {Object.<string,communicator_objects.UnityRLInputProto.IListAgentActionProto>} agentActions
         * @memberof communicator_objects.UnityRLInputProto
         * @instance
         */
        UnityRLInputProto.prototype.agentActions = $util.emptyObject;

        /**
         * UnityRLInputProto command.
         * @member {communicator_objects.CommandProto} command
         * @memberof communicator_objects.UnityRLInputProto
         * @instance
         */
        UnityRLInputProto.prototype.command = 0;

        /**
         * UnityRLInputProto sideChannel.
         * @member {Uint8Array} sideChannel
         * @memberof communicator_objects.UnityRLInputProto
         * @instance
         */
        UnityRLInputProto.prototype.sideChannel = $util.newBuffer([]);

        /**
         * Creates a new UnityRLInputProto instance using the specified properties.
         * @function create
         * @memberof communicator_objects.UnityRLInputProto
         * @static
         * @param {communicator_objects.IUnityRLInputProto=} [properties] Properties to set
         * @returns {communicator_objects.UnityRLInputProto} UnityRLInputProto instance
         */
        UnityRLInputProto.create = function create(properties) {
            return new UnityRLInputProto(properties);
        };

        /**
         * Encodes the specified UnityRLInputProto message. Does not implicitly {@link communicator_objects.UnityRLInputProto.verify|verify} messages.
         * @function encode
         * @memberof communicator_objects.UnityRLInputProto
         * @static
         * @param {communicator_objects.IUnityRLInputProto} message UnityRLInputProto message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        UnityRLInputProto.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.agentActions != null && Object.hasOwnProperty.call(message, "agentActions"))
                for (var keys = Object.keys(message.agentActions), i = 0; i < keys.length; ++i) {
                    writer.uint32(/* id 1, wireType 2 =*/10).fork().uint32(/* id 1, wireType 2 =*/10).string(keys[i]);
                    $root.communicator_objects.UnityRLInputProto.ListAgentActionProto.encode(message.agentActions[keys[i]], writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim().ldelim();
                }
            if (message.command != null && Object.hasOwnProperty.call(message, "command"))
                writer.uint32(/* id 4, wireType 0 =*/32).int32(message.command);
            if (message.sideChannel != null && Object.hasOwnProperty.call(message, "sideChannel"))
                writer.uint32(/* id 5, wireType 2 =*/42).bytes(message.sideChannel);
            return writer;
        };

        /**
         * Encodes the specified UnityRLInputProto message, length delimited. Does not implicitly {@link communicator_objects.UnityRLInputProto.verify|verify} messages.
         * @function encodeDelimited
         * @memberof communicator_objects.UnityRLInputProto
         * @static
         * @param {communicator_objects.IUnityRLInputProto} message UnityRLInputProto message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        UnityRLInputProto.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes an UnityRLInputProto message from the specified reader or buffer.
         * @function decode
         * @memberof communicator_objects.UnityRLInputProto
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {communicator_objects.UnityRLInputProto} UnityRLInputProto
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        UnityRLInputProto.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.communicator_objects.UnityRLInputProto(), key, value;
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    if (message.agentActions === $util.emptyObject)
                        message.agentActions = {};
                    var end2 = reader.uint32() + reader.pos;
                    key = "";
                    value = null;
                    while (reader.pos < end2) {
                        var tag2 = reader.uint32();
                        switch (tag2 >>> 3) {
                        case 1:
                            key = reader.string();
                            break;
                        case 2:
                            value = $root.communicator_objects.UnityRLInputProto.ListAgentActionProto.decode(reader, reader.uint32());
                            break;
                        default:
                            reader.skipType(tag2 & 7);
                            break;
                        }
                    }
                    message.agentActions[key] = value;
                    break;
                case 4:
                    message.command = reader.int32();
                    break;
                case 5:
                    message.sideChannel = reader.bytes();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes an UnityRLInputProto message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof communicator_objects.UnityRLInputProto
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {communicator_objects.UnityRLInputProto} UnityRLInputProto
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        UnityRLInputProto.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies an UnityRLInputProto message.
         * @function verify
         * @memberof communicator_objects.UnityRLInputProto
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        UnityRLInputProto.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.agentActions != null && message.hasOwnProperty("agentActions")) {
                if (!$util.isObject(message.agentActions))
                    return "agentActions: object expected";
                var key = Object.keys(message.agentActions);
                for (var i = 0; i < key.length; ++i) {
                    var error = $root.communicator_objects.UnityRLInputProto.ListAgentActionProto.verify(message.agentActions[key[i]]);
                    if (error)
                        return "agentActions." + error;
                }
            }
            if (message.command != null && message.hasOwnProperty("command"))
                switch (message.command) {
                default:
                    return "command: enum value expected";
                case 0:
                case 1:
                case 2:
                    break;
                }
            if (message.sideChannel != null && message.hasOwnProperty("sideChannel"))
                if (!(message.sideChannel && typeof message.sideChannel.length === "number" || $util.isString(message.sideChannel)))
                    return "sideChannel: buffer expected";
            return null;
        };

        /**
         * Creates an UnityRLInputProto message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof communicator_objects.UnityRLInputProto
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {communicator_objects.UnityRLInputProto} UnityRLInputProto
         */
        UnityRLInputProto.fromObject = function fromObject(object) {
            if (object instanceof $root.communicator_objects.UnityRLInputProto)
                return object;
            var message = new $root.communicator_objects.UnityRLInputProto();
            if (object.agentActions) {
                if (typeof object.agentActions !== "object")
                    throw TypeError(".communicator_objects.UnityRLInputProto.agentActions: object expected");
                message.agentActions = {};
                for (var keys = Object.keys(object.agentActions), i = 0; i < keys.length; ++i) {
                    if (typeof object.agentActions[keys[i]] !== "object")
                        throw TypeError(".communicator_objects.UnityRLInputProto.agentActions: object expected");
                    message.agentActions[keys[i]] = $root.communicator_objects.UnityRLInputProto.ListAgentActionProto.fromObject(object.agentActions[keys[i]]);
                }
            }
            switch (object.command) {
            case "STEP":
            case 0:
                message.command = 0;
                break;
            case "RESET":
            case 1:
                message.command = 1;
                break;
            case "QUIT":
            case 2:
                message.command = 2;
                break;
            }
            if (object.sideChannel != null)
                if (typeof object.sideChannel === "string")
                    $util.base64.decode(object.sideChannel, message.sideChannel = $util.newBuffer($util.base64.length(object.sideChannel)), 0);
                else if (object.sideChannel.length)
                    message.sideChannel = object.sideChannel;
            return message;
        };

        /**
         * Creates a plain object from an UnityRLInputProto message. Also converts values to other types if specified.
         * @function toObject
         * @memberof communicator_objects.UnityRLInputProto
         * @static
         * @param {communicator_objects.UnityRLInputProto} message UnityRLInputProto
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        UnityRLInputProto.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.objects || options.defaults)
                object.agentActions = {};
            if (options.defaults) {
                object.command = options.enums === String ? "STEP" : 0;
                if (options.bytes === String)
                    object.sideChannel = "";
                else {
                    object.sideChannel = [];
                    if (options.bytes !== Array)
                        object.sideChannel = $util.newBuffer(object.sideChannel);
                }
            }
            var keys2;
            if (message.agentActions && (keys2 = Object.keys(message.agentActions)).length) {
                object.agentActions = {};
                for (var j = 0; j < keys2.length; ++j)
                    object.agentActions[keys2[j]] = $root.communicator_objects.UnityRLInputProto.ListAgentActionProto.toObject(message.agentActions[keys2[j]], options);
            }
            if (message.command != null && message.hasOwnProperty("command"))
                object.command = options.enums === String ? $root.communicator_objects.CommandProto[message.command] : message.command;
            if (message.sideChannel != null && message.hasOwnProperty("sideChannel"))
                object.sideChannel = options.bytes === String ? $util.base64.encode(message.sideChannel, 0, message.sideChannel.length) : options.bytes === Array ? Array.prototype.slice.call(message.sideChannel) : message.sideChannel;
            return object;
        };

        /**
         * Converts this UnityRLInputProto to JSON.
         * @function toJSON
         * @memberof communicator_objects.UnityRLInputProto
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        UnityRLInputProto.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        UnityRLInputProto.ListAgentActionProto = (function() {

            /**
             * Properties of a ListAgentActionProto.
             * @memberof communicator_objects.UnityRLInputProto
             * @interface IListAgentActionProto
             * @property {Array.<communicator_objects.IAgentActionProto>|null} [value] ListAgentActionProto value
             */

            /**
             * Constructs a new ListAgentActionProto.
             * @memberof communicator_objects.UnityRLInputProto
             * @classdesc Represents a ListAgentActionProto.
             * @implements IListAgentActionProto
             * @constructor
             * @param {communicator_objects.UnityRLInputProto.IListAgentActionProto=} [properties] Properties to set
             */
            function ListAgentActionProto(properties) {
                this.value = [];
                if (properties)
                    for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                        if (properties[keys[i]] != null)
                            this[keys[i]] = properties[keys[i]];
            }

            /**
             * ListAgentActionProto value.
             * @member {Array.<communicator_objects.IAgentActionProto>} value
             * @memberof communicator_objects.UnityRLInputProto.ListAgentActionProto
             * @instance
             */
            ListAgentActionProto.prototype.value = $util.emptyArray;

            /**
             * Creates a new ListAgentActionProto instance using the specified properties.
             * @function create
             * @memberof communicator_objects.UnityRLInputProto.ListAgentActionProto
             * @static
             * @param {communicator_objects.UnityRLInputProto.IListAgentActionProto=} [properties] Properties to set
             * @returns {communicator_objects.UnityRLInputProto.ListAgentActionProto} ListAgentActionProto instance
             */
            ListAgentActionProto.create = function create(properties) {
                return new ListAgentActionProto(properties);
            };

            /**
             * Encodes the specified ListAgentActionProto message. Does not implicitly {@link communicator_objects.UnityRLInputProto.ListAgentActionProto.verify|verify} messages.
             * @function encode
             * @memberof communicator_objects.UnityRLInputProto.ListAgentActionProto
             * @static
             * @param {communicator_objects.UnityRLInputProto.IListAgentActionProto} message ListAgentActionProto message or plain object to encode
             * @param {$protobuf.Writer} [writer] Writer to encode to
             * @returns {$protobuf.Writer} Writer
             */
            ListAgentActionProto.encode = function encode(message, writer) {
                if (!writer)
                    writer = $Writer.create();
                if (message.value != null && message.value.length)
                    for (var i = 0; i < message.value.length; ++i)
                        $root.communicator_objects.AgentActionProto.encode(message.value[i], writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim();
                return writer;
            };

            /**
             * Encodes the specified ListAgentActionProto message, length delimited. Does not implicitly {@link communicator_objects.UnityRLInputProto.ListAgentActionProto.verify|verify} messages.
             * @function encodeDelimited
             * @memberof communicator_objects.UnityRLInputProto.ListAgentActionProto
             * @static
             * @param {communicator_objects.UnityRLInputProto.IListAgentActionProto} message ListAgentActionProto message or plain object to encode
             * @param {$protobuf.Writer} [writer] Writer to encode to
             * @returns {$protobuf.Writer} Writer
             */
            ListAgentActionProto.encodeDelimited = function encodeDelimited(message, writer) {
                return this.encode(message, writer).ldelim();
            };

            /**
             * Decodes a ListAgentActionProto message from the specified reader or buffer.
             * @function decode
             * @memberof communicator_objects.UnityRLInputProto.ListAgentActionProto
             * @static
             * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
             * @param {number} [length] Message length if known beforehand
             * @returns {communicator_objects.UnityRLInputProto.ListAgentActionProto} ListAgentActionProto
             * @throws {Error} If the payload is not a reader or valid buffer
             * @throws {$protobuf.util.ProtocolError} If required fields are missing
             */
            ListAgentActionProto.decode = function decode(reader, length) {
                if (!(reader instanceof $Reader))
                    reader = $Reader.create(reader);
                var end = length === undefined ? reader.len : reader.pos + length, message = new $root.communicator_objects.UnityRLInputProto.ListAgentActionProto();
                while (reader.pos < end) {
                    var tag = reader.uint32();
                    switch (tag >>> 3) {
                    case 1:
                        if (!(message.value && message.value.length))
                            message.value = [];
                        message.value.push($root.communicator_objects.AgentActionProto.decode(reader, reader.uint32()));
                        break;
                    default:
                        reader.skipType(tag & 7);
                        break;
                    }
                }
                return message;
            };

            /**
             * Decodes a ListAgentActionProto message from the specified reader or buffer, length delimited.
             * @function decodeDelimited
             * @memberof communicator_objects.UnityRLInputProto.ListAgentActionProto
             * @static
             * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
             * @returns {communicator_objects.UnityRLInputProto.ListAgentActionProto} ListAgentActionProto
             * @throws {Error} If the payload is not a reader or valid buffer
             * @throws {$protobuf.util.ProtocolError} If required fields are missing
             */
            ListAgentActionProto.decodeDelimited = function decodeDelimited(reader) {
                if (!(reader instanceof $Reader))
                    reader = new $Reader(reader);
                return this.decode(reader, reader.uint32());
            };

            /**
             * Verifies a ListAgentActionProto message.
             * @function verify
             * @memberof communicator_objects.UnityRLInputProto.ListAgentActionProto
             * @static
             * @param {Object.<string,*>} message Plain object to verify
             * @returns {string|null} `null` if valid, otherwise the reason why it is not
             */
            ListAgentActionProto.verify = function verify(message) {
                if (typeof message !== "object" || message === null)
                    return "object expected";
                if (message.value != null && message.hasOwnProperty("value")) {
                    if (!Array.isArray(message.value))
                        return "value: array expected";
                    for (var i = 0; i < message.value.length; ++i) {
                        var error = $root.communicator_objects.AgentActionProto.verify(message.value[i]);
                        if (error)
                            return "value." + error;
                    }
                }
                return null;
            };

            /**
             * Creates a ListAgentActionProto message from a plain object. Also converts values to their respective internal types.
             * @function fromObject
             * @memberof communicator_objects.UnityRLInputProto.ListAgentActionProto
             * @static
             * @param {Object.<string,*>} object Plain object
             * @returns {communicator_objects.UnityRLInputProto.ListAgentActionProto} ListAgentActionProto
             */
            ListAgentActionProto.fromObject = function fromObject(object) {
                if (object instanceof $root.communicator_objects.UnityRLInputProto.ListAgentActionProto)
                    return object;
                var message = new $root.communicator_objects.UnityRLInputProto.ListAgentActionProto();
                if (object.value) {
                    if (!Array.isArray(object.value))
                        throw TypeError(".communicator_objects.UnityRLInputProto.ListAgentActionProto.value: array expected");
                    message.value = [];
                    for (var i = 0; i < object.value.length; ++i) {
                        if (typeof object.value[i] !== "object")
                            throw TypeError(".communicator_objects.UnityRLInputProto.ListAgentActionProto.value: object expected");
                        message.value[i] = $root.communicator_objects.AgentActionProto.fromObject(object.value[i]);
                    }
                }
                return message;
            };

            /**
             * Creates a plain object from a ListAgentActionProto message. Also converts values to other types if specified.
             * @function toObject
             * @memberof communicator_objects.UnityRLInputProto.ListAgentActionProto
             * @static
             * @param {communicator_objects.UnityRLInputProto.ListAgentActionProto} message ListAgentActionProto
             * @param {$protobuf.IConversionOptions} [options] Conversion options
             * @returns {Object.<string,*>} Plain object
             */
            ListAgentActionProto.toObject = function toObject(message, options) {
                if (!options)
                    options = {};
                var object = {};
                if (options.arrays || options.defaults)
                    object.value = [];
                if (message.value && message.value.length) {
                    object.value = [];
                    for (var j = 0; j < message.value.length; ++j)
                        object.value[j] = $root.communicator_objects.AgentActionProto.toObject(message.value[j], options);
                }
                return object;
            };

            /**
             * Converts this ListAgentActionProto to JSON.
             * @function toJSON
             * @memberof communicator_objects.UnityRLInputProto.ListAgentActionProto
             * @instance
             * @returns {Object.<string,*>} JSON object
             */
            ListAgentActionProto.prototype.toJSON = function toJSON() {
                return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
            };

            return ListAgentActionProto;
        })();

        return UnityRLInputProto;
    })();

    communicator_objects.UnityRLOutputProto = (function() {

        /**
         * Properties of an UnityRLOutputProto.
         * @memberof communicator_objects
         * @interface IUnityRLOutputProto
         * @property {Object.<string,communicator_objects.UnityRLOutputProto.IListAgentInfoProto>|null} [agentInfos] UnityRLOutputProto agentInfos
         * @property {Uint8Array|null} [sideChannel] UnityRLOutputProto sideChannel
         */

        /**
         * Constructs a new UnityRLOutputProto.
         * @memberof communicator_objects
         * @classdesc Represents an UnityRLOutputProto.
         * @implements IUnityRLOutputProto
         * @constructor
         * @param {communicator_objects.IUnityRLOutputProto=} [properties] Properties to set
         */
        function UnityRLOutputProto(properties) {
            this.agentInfos = {};
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * UnityRLOutputProto agentInfos.
         * @member {Object.<string,communicator_objects.UnityRLOutputProto.IListAgentInfoProto>} agentInfos
         * @memberof communicator_objects.UnityRLOutputProto
         * @instance
         */
        UnityRLOutputProto.prototype.agentInfos = $util.emptyObject;

        /**
         * UnityRLOutputProto sideChannel.
         * @member {Uint8Array} sideChannel
         * @memberof communicator_objects.UnityRLOutputProto
         * @instance
         */
        UnityRLOutputProto.prototype.sideChannel = $util.newBuffer([]);

        /**
         * Creates a new UnityRLOutputProto instance using the specified properties.
         * @function create
         * @memberof communicator_objects.UnityRLOutputProto
         * @static
         * @param {communicator_objects.IUnityRLOutputProto=} [properties] Properties to set
         * @returns {communicator_objects.UnityRLOutputProto} UnityRLOutputProto instance
         */
        UnityRLOutputProto.create = function create(properties) {
            return new UnityRLOutputProto(properties);
        };

        /**
         * Encodes the specified UnityRLOutputProto message. Does not implicitly {@link communicator_objects.UnityRLOutputProto.verify|verify} messages.
         * @function encode
         * @memberof communicator_objects.UnityRLOutputProto
         * @static
         * @param {communicator_objects.IUnityRLOutputProto} message UnityRLOutputProto message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        UnityRLOutputProto.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.agentInfos != null && Object.hasOwnProperty.call(message, "agentInfos"))
                for (var keys = Object.keys(message.agentInfos), i = 0; i < keys.length; ++i) {
                    writer.uint32(/* id 2, wireType 2 =*/18).fork().uint32(/* id 1, wireType 2 =*/10).string(keys[i]);
                    $root.communicator_objects.UnityRLOutputProto.ListAgentInfoProto.encode(message.agentInfos[keys[i]], writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim().ldelim();
                }
            if (message.sideChannel != null && Object.hasOwnProperty.call(message, "sideChannel"))
                writer.uint32(/* id 3, wireType 2 =*/26).bytes(message.sideChannel);
            return writer;
        };

        /**
         * Encodes the specified UnityRLOutputProto message, length delimited. Does not implicitly {@link communicator_objects.UnityRLOutputProto.verify|verify} messages.
         * @function encodeDelimited
         * @memberof communicator_objects.UnityRLOutputProto
         * @static
         * @param {communicator_objects.IUnityRLOutputProto} message UnityRLOutputProto message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        UnityRLOutputProto.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes an UnityRLOutputProto message from the specified reader or buffer.
         * @function decode
         * @memberof communicator_objects.UnityRLOutputProto
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {communicator_objects.UnityRLOutputProto} UnityRLOutputProto
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        UnityRLOutputProto.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.communicator_objects.UnityRLOutputProto(), key, value;
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 2:
                    if (message.agentInfos === $util.emptyObject)
                        message.agentInfos = {};
                    var end2 = reader.uint32() + reader.pos;
                    key = "";
                    value = null;
                    while (reader.pos < end2) {
                        var tag2 = reader.uint32();
                        switch (tag2 >>> 3) {
                        case 1:
                            key = reader.string();
                            break;
                        case 2:
                            value = $root.communicator_objects.UnityRLOutputProto.ListAgentInfoProto.decode(reader, reader.uint32());
                            break;
                        default:
                            reader.skipType(tag2 & 7);
                            break;
                        }
                    }
                    message.agentInfos[key] = value;
                    break;
                case 3:
                    message.sideChannel = reader.bytes();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes an UnityRLOutputProto message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof communicator_objects.UnityRLOutputProto
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {communicator_objects.UnityRLOutputProto} UnityRLOutputProto
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        UnityRLOutputProto.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies an UnityRLOutputProto message.
         * @function verify
         * @memberof communicator_objects.UnityRLOutputProto
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        UnityRLOutputProto.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.agentInfos != null && message.hasOwnProperty("agentInfos")) {
                if (!$util.isObject(message.agentInfos))
                    return "agentInfos: object expected";
                var key = Object.keys(message.agentInfos);
                for (var i = 0; i < key.length; ++i) {
                    var error = $root.communicator_objects.UnityRLOutputProto.ListAgentInfoProto.verify(message.agentInfos[key[i]]);
                    if (error)
                        return "agentInfos." + error;
                }
            }
            if (message.sideChannel != null && message.hasOwnProperty("sideChannel"))
                if (!(message.sideChannel && typeof message.sideChannel.length === "number" || $util.isString(message.sideChannel)))
                    return "sideChannel: buffer expected";
            return null;
        };

        /**
         * Creates an UnityRLOutputProto message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof communicator_objects.UnityRLOutputProto
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {communicator_objects.UnityRLOutputProto} UnityRLOutputProto
         */
        UnityRLOutputProto.fromObject = function fromObject(object) {
            if (object instanceof $root.communicator_objects.UnityRLOutputProto)
                return object;
            var message = new $root.communicator_objects.UnityRLOutputProto();
            if (object.agentInfos) {
                if (typeof object.agentInfos !== "object")
                    throw TypeError(".communicator_objects.UnityRLOutputProto.agentInfos: object expected");
                message.agentInfos = {};
                for (var keys = Object.keys(object.agentInfos), i = 0; i < keys.length; ++i) {
                    if (typeof object.agentInfos[keys[i]] !== "object")
                        throw TypeError(".communicator_objects.UnityRLOutputProto.agentInfos: object expected");
                    message.agentInfos[keys[i]] = $root.communicator_objects.UnityRLOutputProto.ListAgentInfoProto.fromObject(object.agentInfos[keys[i]]);
                }
            }
            if (object.sideChannel != null)
                if (typeof object.sideChannel === "string")
                    $util.base64.decode(object.sideChannel, message.sideChannel = $util.newBuffer($util.base64.length(object.sideChannel)), 0);
                else if (object.sideChannel.length)
                    message.sideChannel = object.sideChannel;
            return message;
        };

        /**
         * Creates a plain object from an UnityRLOutputProto message. Also converts values to other types if specified.
         * @function toObject
         * @memberof communicator_objects.UnityRLOutputProto
         * @static
         * @param {communicator_objects.UnityRLOutputProto} message UnityRLOutputProto
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        UnityRLOutputProto.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.objects || options.defaults)
                object.agentInfos = {};
            if (options.defaults)
                if (options.bytes === String)
                    object.sideChannel = "";
                else {
                    object.sideChannel = [];
                    if (options.bytes !== Array)
                        object.sideChannel = $util.newBuffer(object.sideChannel);
                }
            var keys2;
            if (message.agentInfos && (keys2 = Object.keys(message.agentInfos)).length) {
                object.agentInfos = {};
                for (var j = 0; j < keys2.length; ++j)
                    object.agentInfos[keys2[j]] = $root.communicator_objects.UnityRLOutputProto.ListAgentInfoProto.toObject(message.agentInfos[keys2[j]], options);
            }
            if (message.sideChannel != null && message.hasOwnProperty("sideChannel"))
                object.sideChannel = options.bytes === String ? $util.base64.encode(message.sideChannel, 0, message.sideChannel.length) : options.bytes === Array ? Array.prototype.slice.call(message.sideChannel) : message.sideChannel;
            return object;
        };

        /**
         * Converts this UnityRLOutputProto to JSON.
         * @function toJSON
         * @memberof communicator_objects.UnityRLOutputProto
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        UnityRLOutputProto.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        UnityRLOutputProto.ListAgentInfoProto = (function() {

            /**
             * Properties of a ListAgentInfoProto.
             * @memberof communicator_objects.UnityRLOutputProto
             * @interface IListAgentInfoProto
             * @property {Array.<communicator_objects.IAgentInfoProto>|null} [value] ListAgentInfoProto value
             */

            /**
             * Constructs a new ListAgentInfoProto.
             * @memberof communicator_objects.UnityRLOutputProto
             * @classdesc Represents a ListAgentInfoProto.
             * @implements IListAgentInfoProto
             * @constructor
             * @param {communicator_objects.UnityRLOutputProto.IListAgentInfoProto=} [properties] Properties to set
             */
            function ListAgentInfoProto(properties) {
                this.value = [];
                if (properties)
                    for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                        if (properties[keys[i]] != null)
                            this[keys[i]] = properties[keys[i]];
            }

            /**
             * ListAgentInfoProto value.
             * @member {Array.<communicator_objects.IAgentInfoProto>} value
             * @memberof communicator_objects.UnityRLOutputProto.ListAgentInfoProto
             * @instance
             */
            ListAgentInfoProto.prototype.value = $util.emptyArray;

            /**
             * Creates a new ListAgentInfoProto instance using the specified properties.
             * @function create
             * @memberof communicator_objects.UnityRLOutputProto.ListAgentInfoProto
             * @static
             * @param {communicator_objects.UnityRLOutputProto.IListAgentInfoProto=} [properties] Properties to set
             * @returns {communicator_objects.UnityRLOutputProto.ListAgentInfoProto} ListAgentInfoProto instance
             */
            ListAgentInfoProto.create = function create(properties) {
                return new ListAgentInfoProto(properties);
            };

            /**
             * Encodes the specified ListAgentInfoProto message. Does not implicitly {@link communicator_objects.UnityRLOutputProto.ListAgentInfoProto.verify|verify} messages.
             * @function encode
             * @memberof communicator_objects.UnityRLOutputProto.ListAgentInfoProto
             * @static
             * @param {communicator_objects.UnityRLOutputProto.IListAgentInfoProto} message ListAgentInfoProto message or plain object to encode
             * @param {$protobuf.Writer} [writer] Writer to encode to
             * @returns {$protobuf.Writer} Writer
             */
            ListAgentInfoProto.encode = function encode(message, writer) {
                if (!writer)
                    writer = $Writer.create();
                if (message.value != null && message.value.length)
                    for (var i = 0; i < message.value.length; ++i)
                        $root.communicator_objects.AgentInfoProto.encode(message.value[i], writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim();
                return writer;
            };

            /**
             * Encodes the specified ListAgentInfoProto message, length delimited. Does not implicitly {@link communicator_objects.UnityRLOutputProto.ListAgentInfoProto.verify|verify} messages.
             * @function encodeDelimited
             * @memberof communicator_objects.UnityRLOutputProto.ListAgentInfoProto
             * @static
             * @param {communicator_objects.UnityRLOutputProto.IListAgentInfoProto} message ListAgentInfoProto message or plain object to encode
             * @param {$protobuf.Writer} [writer] Writer to encode to
             * @returns {$protobuf.Writer} Writer
             */
            ListAgentInfoProto.encodeDelimited = function encodeDelimited(message, writer) {
                return this.encode(message, writer).ldelim();
            };

            /**
             * Decodes a ListAgentInfoProto message from the specified reader or buffer.
             * @function decode
             * @memberof communicator_objects.UnityRLOutputProto.ListAgentInfoProto
             * @static
             * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
             * @param {number} [length] Message length if known beforehand
             * @returns {communicator_objects.UnityRLOutputProto.ListAgentInfoProto} ListAgentInfoProto
             * @throws {Error} If the payload is not a reader or valid buffer
             * @throws {$protobuf.util.ProtocolError} If required fields are missing
             */
            ListAgentInfoProto.decode = function decode(reader, length) {
                if (!(reader instanceof $Reader))
                    reader = $Reader.create(reader);
                var end = length === undefined ? reader.len : reader.pos + length, message = new $root.communicator_objects.UnityRLOutputProto.ListAgentInfoProto();
                while (reader.pos < end) {
                    var tag = reader.uint32();
                    switch (tag >>> 3) {
                    case 1:
                        if (!(message.value && message.value.length))
                            message.value = [];
                        message.value.push($root.communicator_objects.AgentInfoProto.decode(reader, reader.uint32()));
                        break;
                    default:
                        reader.skipType(tag & 7);
                        break;
                    }
                }
                return message;
            };

            /**
             * Decodes a ListAgentInfoProto message from the specified reader or buffer, length delimited.
             * @function decodeDelimited
             * @memberof communicator_objects.UnityRLOutputProto.ListAgentInfoProto
             * @static
             * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
             * @returns {communicator_objects.UnityRLOutputProto.ListAgentInfoProto} ListAgentInfoProto
             * @throws {Error} If the payload is not a reader or valid buffer
             * @throws {$protobuf.util.ProtocolError} If required fields are missing
             */
            ListAgentInfoProto.decodeDelimited = function decodeDelimited(reader) {
                if (!(reader instanceof $Reader))
                    reader = new $Reader(reader);
                return this.decode(reader, reader.uint32());
            };

            /**
             * Verifies a ListAgentInfoProto message.
             * @function verify
             * @memberof communicator_objects.UnityRLOutputProto.ListAgentInfoProto
             * @static
             * @param {Object.<string,*>} message Plain object to verify
             * @returns {string|null} `null` if valid, otherwise the reason why it is not
             */
            ListAgentInfoProto.verify = function verify(message) {
                if (typeof message !== "object" || message === null)
                    return "object expected";
                if (message.value != null && message.hasOwnProperty("value")) {
                    if (!Array.isArray(message.value))
                        return "value: array expected";
                    for (var i = 0; i < message.value.length; ++i) {
                        var error = $root.communicator_objects.AgentInfoProto.verify(message.value[i]);
                        if (error)
                            return "value." + error;
                    }
                }
                return null;
            };

            /**
             * Creates a ListAgentInfoProto message from a plain object. Also converts values to their respective internal types.
             * @function fromObject
             * @memberof communicator_objects.UnityRLOutputProto.ListAgentInfoProto
             * @static
             * @param {Object.<string,*>} object Plain object
             * @returns {communicator_objects.UnityRLOutputProto.ListAgentInfoProto} ListAgentInfoProto
             */
            ListAgentInfoProto.fromObject = function fromObject(object) {
                if (object instanceof $root.communicator_objects.UnityRLOutputProto.ListAgentInfoProto)
                    return object;
                var message = new $root.communicator_objects.UnityRLOutputProto.ListAgentInfoProto();
                if (object.value) {
                    if (!Array.isArray(object.value))
                        throw TypeError(".communicator_objects.UnityRLOutputProto.ListAgentInfoProto.value: array expected");
                    message.value = [];
                    for (var i = 0; i < object.value.length; ++i) {
                        if (typeof object.value[i] !== "object")
                            throw TypeError(".communicator_objects.UnityRLOutputProto.ListAgentInfoProto.value: object expected");
                        message.value[i] = $root.communicator_objects.AgentInfoProto.fromObject(object.value[i]);
                    }
                }
                return message;
            };

            /**
             * Creates a plain object from a ListAgentInfoProto message. Also converts values to other types if specified.
             * @function toObject
             * @memberof communicator_objects.UnityRLOutputProto.ListAgentInfoProto
             * @static
             * @param {communicator_objects.UnityRLOutputProto.ListAgentInfoProto} message ListAgentInfoProto
             * @param {$protobuf.IConversionOptions} [options] Conversion options
             * @returns {Object.<string,*>} Plain object
             */
            ListAgentInfoProto.toObject = function toObject(message, options) {
                if (!options)
                    options = {};
                var object = {};
                if (options.arrays || options.defaults)
                    object.value = [];
                if (message.value && message.value.length) {
                    object.value = [];
                    for (var j = 0; j < message.value.length; ++j)
                        object.value[j] = $root.communicator_objects.AgentInfoProto.toObject(message.value[j], options);
                }
                return object;
            };

            /**
             * Converts this ListAgentInfoProto to JSON.
             * @function toJSON
             * @memberof communicator_objects.UnityRLOutputProto.ListAgentInfoProto
             * @instance
             * @returns {Object.<string,*>} JSON object
             */
            ListAgentInfoProto.prototype.toJSON = function toJSON() {
                return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
            };

            return ListAgentInfoProto;
        })();

        return UnityRLOutputProto;
    })();

    communicator_objects.UnityToExternalProto = (function() {

        /**
         * Constructs a new UnityToExternalProto service.
         * @memberof communicator_objects
         * @classdesc Represents an UnityToExternalProto
         * @extends $protobuf.rpc.Service
         * @constructor
         * @param {$protobuf.RPCImpl} rpcImpl RPC implementation
         * @param {boolean} [requestDelimited=false] Whether requests are length-delimited
         * @param {boolean} [responseDelimited=false] Whether responses are length-delimited
         */
        function UnityToExternalProto(rpcImpl, requestDelimited, responseDelimited) {
            $protobuf.rpc.Service.call(this, rpcImpl, requestDelimited, responseDelimited);
        }

        (UnityToExternalProto.prototype = Object.create($protobuf.rpc.Service.prototype)).constructor = UnityToExternalProto;

        /**
         * Creates new UnityToExternalProto service using the specified rpc implementation.
         * @function create
         * @memberof communicator_objects.UnityToExternalProto
         * @static
         * @param {$protobuf.RPCImpl} rpcImpl RPC implementation
         * @param {boolean} [requestDelimited=false] Whether requests are length-delimited
         * @param {boolean} [responseDelimited=false] Whether responses are length-delimited
         * @returns {UnityToExternalProto} RPC service. Useful where requests and/or responses are streamed.
         */
        UnityToExternalProto.create = function create(rpcImpl, requestDelimited, responseDelimited) {
            return new this(rpcImpl, requestDelimited, responseDelimited);
        };

        /**
         * Callback as used by {@link communicator_objects.UnityToExternalProto#exchange}.
         * @memberof communicator_objects.UnityToExternalProto
         * @typedef ExchangeCallback
         * @type {function}
         * @param {Error|null} error Error, if any
         * @param {communicator_objects.UnityMessageProto} [response] UnityMessageProto
         */

        /**
         * Calls Exchange.
         * @function exchange
         * @memberof communicator_objects.UnityToExternalProto
         * @instance
         * @param {communicator_objects.IUnityMessageProto} request UnityMessageProto message or plain object
         * @param {communicator_objects.UnityToExternalProto.ExchangeCallback} callback Node-style callback called with the error, if any, and UnityMessageProto
         * @returns {undefined}
         * @variation 1
         */
        Object.defineProperty(UnityToExternalProto.prototype.exchange = function exchange(request, callback) {
            return this.rpcCall(exchange, $root.communicator_objects.UnityMessageProto, $root.communicator_objects.UnityMessageProto, request, callback);
        }, "name", { value: "Exchange" });

        /**
         * Calls Exchange.
         * @function exchange
         * @memberof communicator_objects.UnityToExternalProto
         * @instance
         * @param {communicator_objects.IUnityMessageProto} request UnityMessageProto message or plain object
         * @returns {Promise<communicator_objects.UnityMessageProto>} Promise
         * @variation 2
         */

        return UnityToExternalProto;
    })();

    return communicator_objects;
})();

module.exports = $root;
